diff options
author | Greg Wilkins | 2014-08-29 05:36:19 +0000 |
---|---|---|
committer | Greg Wilkins | 2014-08-29 05:36:19 +0000 |
commit | 69390954dc15acc389479b647f290da121ccc9de (patch) | |
tree | 2bf0584d27c29566f1cb89d613b04f98ff9c3c0a | |
parent | eee2ba206e219a289b8a17e8ef663d7b63e4e4c4 (diff) | |
download | org.eclipse.jetty.project-69390954dc15acc389479b647f290da121ccc9de.tar.gz org.eclipse.jetty.project-69390954dc15acc389479b647f290da121ccc9de.tar.xz org.eclipse.jetty.project-69390954dc15acc389479b647f290da121ccc9de.zip |
435322 acceptor and selector configuration/priority
11 files changed, 221 insertions, 67 deletions
diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java index 0e6fd889da..5728259331 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java @@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.util.ConcurrentArrayQueue; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.Dumpable; @@ -65,6 +66,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa private final ManagedSelector[] _selectors; private long _connectTimeout = DEFAULT_CONNECT_TIMEOUT; private long _selectorIndex; + private int _priorityDelta; protected SelectorManager(Executor executor, Scheduler scheduler) { @@ -110,6 +112,33 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa _connectTimeout = milliseconds; } + + @ManagedAttribute("The priority delta to apply to selector threads") + public int getSelectorPriorityDelta() + { + return _priorityDelta; + } + + /* ------------------------------------------------------------ */ + /** Set the selector thread priority delta. + * <p>This allows the selector threads to run at a different priority. + * Typically this would be used to lower the priority to give preference + * to handling previously accepted connections rather than accepting + * new connections</p> + * @param selectorPriorityDelta + */ + public void setSelectorPriorityDelta(int selectorPriorityDelta) + { + int old=_priorityDelta; + _priorityDelta = selectorPriorityDelta; + if (old!=selectorPriorityDelta && isStarted()) + { + for (ManagedSelector selector : _selectors) + if (selector._thread!=null) + selector._thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,selector._thread.getPriority()-old+selectorPriorityDelta))); + } + } + /** * Executes the given task in a different thread. * @@ -479,8 +508,12 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa { _thread = Thread.currentThread(); String name = _thread.getName(); + int priority=_thread.getPriority(); try { + if (_priorityDelta!=0) + _thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_priorityDelta))); + _thread.setName(name + "-selector-" + SelectorManager.this.getClass().getSimpleName()+"@"+Integer.toHexString(SelectorManager.this.hashCode())+"/"+_id); if (LOG.isDebugEnabled()) LOG.debug("Starting {} on {}", _thread, this); @@ -494,6 +527,8 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa if (LOG.isDebugEnabled()) LOG.debug("Stopped {} on {}", _thread, this); _thread.setName(name); + if (_priorityDelta!=0) + _thread.setPriority(priority); } } diff --git a/jetty-server/src/main/config/etc/jetty-http.xml b/jetty-server/src/main/config/etc/jetty-http.xml index c3f74f3e66..75012f36af 100644 --- a/jetty-server/src/main/config/etc/jetty-http.xml +++ b/jetty-server/src/main/config/etc/jetty-http.xml @@ -22,6 +22,8 @@ <Arg> <New class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"><Ref refid="Server" /></Arg> + <Arg name="acceptors" type="int"><Property name="http.acceptors" default="-1"/></Arg> + <Arg name="selectors" type="int"><Property name="http.selectors" default="-1"/></Arg> <Arg name="factories"> <Array type="org.eclipse.jetty.server.ConnectionFactory"> <Item> @@ -35,6 +37,8 @@ <Set name="port"><Property name="jetty.port" default="80" /></Set> <Set name="idleTimeout"><Property name="http.timeout" default="30000"/></Set> <Set name="soLingerTime"><Property name="http.soLingerTime" default="-1"/></Set> + <Set name="acceptorPriorityDelta"><Property name="http.acceptorPriorityDelta" default="0"/></Set> + <Set name="selectorPriorityDelta"><Property name="http.selectorPriorityDelta" default="0"/></Set> </New> </Arg> </Call> diff --git a/jetty-server/src/main/config/etc/jetty-https.xml b/jetty-server/src/main/config/etc/jetty-https.xml index 419f8d19ee..a019cb90e7 100644 --- a/jetty-server/src/main/config/etc/jetty-https.xml +++ b/jetty-server/src/main/config/etc/jetty-https.xml @@ -23,26 +23,30 @@ <Arg> <New class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"><Ref refid="Server" /></Arg> - <Arg name="factories"> - <Array type="org.eclipse.jetty.server.ConnectionFactory"> - <Item> - <New class="org.eclipse.jetty.server.SslConnectionFactory"> - <Arg name="next">http/1.1</Arg> - <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg> - </New> - </Item> - <Item> - <New class="org.eclipse.jetty.server.HttpConnectionFactory"> - <Arg name="config"><Ref refid="sslHttpConfig"/></Arg> - </New> - </Item> - </Array> - </Arg> - <Set name="host"><Property name="jetty.host" /></Set> - <Set name="port"><Property name="https.port" default="443" /></Set> - <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set> - <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set> - </New> + <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg> + <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg> + <Arg name="factories"> + <Array type="org.eclipse.jetty.server.ConnectionFactory"> + <Item> + <New class="org.eclipse.jetty.server.SslConnectionFactory"> + <Arg name="next">http/1.1</Arg> + <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg> + </New> + </Item> + <Item> + <New class="org.eclipse.jetty.server.HttpConnectionFactory"> + <Arg name="config"><Ref refid="sslHttpConfig"/></Arg> + </New> + </Item> + </Array> + </Arg> + <Set name="host"><Property name="jetty.host" /></Set> + <Set name="port"><Property name="https.port" default="443" /></Set> + <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set> + <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set> + <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set> + <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set> + </New> </Arg> </Call> </Configure> diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod index 8740af3c7b..dc34bc3cb9 100644 --- a/jetty-server/src/main/config/modules/http.mod +++ b/jetty-server/src/main/config/modules/http.mod @@ -9,10 +9,19 @@ server etc/jetty-http.xml [ini-template] -## HTTP Connector Configuration -# HTTP port to listen on +### HTTP Connector Configuration + +## HTTP port to listen on jetty.port=8080 -# HTTP idle timeout in milliseconds + +## HTTP idle timeout in milliseconds http.timeout=30000 -# HTTP Socket.soLingerTime in seconds. (-1 to disable) + +## HTTP Socket.soLingerTime in seconds. (-1 to disable) # http.soLingerTime=-1 + +## Parameters to control the number and priority of acceptors and selectors +# http.selectors=1 +# http.acceptors=1 +# http.selectorPriorityDelta=0 +# http.acceptorPriorityDelta=0 diff --git a/jetty-server/src/main/config/modules/ssl.mod b/jetty-server/src/main/config/modules/ssl.mod index 449f58104f..ef471929f3 100644 --- a/jetty-server/src/main/config/modules/ssl.mod +++ b/jetty-server/src/main/config/modules/ssl.mod @@ -12,24 +12,29 @@ etc/jetty-ssl.xml http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/plain/jetty-server/src/main/config/etc/keystore|etc/keystore [ini-template] -## SSL Keystore Configuration +### SSL Keystore Configuration # define the port to use for secure redirection jetty.secure.port=8443 -# Setup a demonstration keystore and truststore +## Setup a demonstration keystore and truststore jetty.keystore=etc/keystore jetty.truststore=etc/keystore -# Set the demonstration passwords. -# Note that OBF passwords are not secure, just protected from casual observation -# See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html +## Set the demonstration passwords. +## Note that OBF passwords are not secure, just protected from casual observation +## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4 jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g jetty.truststore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4 -# Set the client auth behavior -# Set to true if client certificate authentication is required +### Set the client auth behavior +## Set to true if client certificate authentication is required # jetty.ssl.needClientAuth=true -# Set to true if client certificate authentication is desired +## Set to true if client certificate authentication is desired # jetty.ssl.wantClientAuth=true +## Parameters to control the number and priority of acceptors and selectors +# ssl.selectors=1 +# ssl.acceptors=1 +# ssl.selectorPriorityDelta=0 +# ssl.acceptorPriorityDelta=0 diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java index 3106eec257..860799442f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java @@ -147,6 +147,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co private String _defaultProtocol; private ConnectionFactory _defaultConnectionFactory; private String _name; + private int _acceptorPriorityDelta; /** @@ -399,6 +400,30 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co } } + @ManagedAttribute("The priority delta to apply to acceptor threads") + public int getAcceptorPriorityDelta() + { + return _acceptorPriorityDelta; + } + + /* ------------------------------------------------------------ */ + /** Set the acceptor thread priority delta. + * <p>This allows the acceptor thread to run at a different priority. + * Typically this would be used to lower the priority to give preference + * to handling previously accepted connections rather than accepting + * new connections</p> + * @param acceptorPriorityDelta + */ + public void setAcceptorPriorityDelta(int acceptorPriorityDelta) + { + int old=_acceptorPriorityDelta; + _acceptorPriorityDelta = acceptorPriorityDelta; + if (old!=acceptorPriorityDelta && isStarted()) + { + for (Thread thread : _acceptors) + thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,thread.getPriority()-old+acceptorPriorityDelta))); + } + } @Override @ManagedAttribute("Protocols supported by this connector") @@ -452,14 +477,18 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co @Override public void run() { - Thread current = Thread.currentThread(); - String name=current.getName(); + final Thread thread = Thread.currentThread(); + String name=thread.getName(); _name=String.format("%s-acceptor-%d@%x-%s",name,_acceptor,hashCode(),AbstractConnector.this.toString()); - current.setName(_name); + thread.setName(_name); + + int priority=thread.getPriority(); + if (_acceptorPriorityDelta!=0) + thread.setPriority(Math.max(Thread.MIN_PRIORITY,Math.min(Thread.MAX_PRIORITY,priority+_acceptorPriorityDelta))); synchronized (AbstractConnector.this) { - _acceptors[_acceptor] = current; + _acceptors[_acceptor] = thread; } try @@ -481,7 +510,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co } finally { - current.setName(name); + thread.setName(name); + if (_acceptorPriorityDelta!=0) + thread.setPriority(priority); synchronized (AbstractConnector.this) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java index f4da30c004..87daedf02b 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java @@ -113,6 +113,26 @@ public class ServerConnector extends AbstractNetworkConnector { this(server,null,null,null,acceptors,selectors,new HttpConnectionFactory()); } + + /* ------------------------------------------------------------ */ + /** HTTP Server Connection. + * <p>Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.</p> + * @param server The {@link Server} this connector will accept connection for. + * @param acceptors + * the number of acceptor threads to use, or -1 for a default value. Acceptors accept new TCP/IP connections. If 0, then + * the selector threads are used to accept connections. + * @param selectors + * the number of selector threads, or -1 for a default value. Selectors notice and schedule established connection that can make IO progress. + * @param factories Zero or more {@link ConnectionFactory} instances used to create and configure connections. + */ + public ServerConnector( + @Name("server") Server server, + @Name("acceptors") int acceptors, + @Name("selectors") int selectors, + @Name("factories") ConnectionFactory... factories) + { + this(server,null,null,null,acceptors,selectors,factories); + } /* ------------------------------------------------------------ */ /** Generic Server Connection with default configuration. @@ -229,6 +249,25 @@ public class ServerConnector extends AbstractNetworkConnector return channel!=null && channel.isOpen(); } + + @ManagedAttribute("The priority delta to apply to selector threads") + public int getSelectorPriorityDelta() + { + return _manager.getSelectorPriorityDelta(); + } + + /** Set the selector thread priority delta. + * <p>This allows the selector threads to run at a different priority. + * Typically this would be used to lower the priority to give preference + * to handling previously accepted requests rather than accepting + * new requests</p> + * @param selectorPriorityDelta + */ + public void setSelectorPriorityDelta(int selectorPriorityDelta) + { + _manager.setSelectorPriorityDelta(selectorPriorityDelta); + } + /** * @return whether this connector uses a channel inherited from the JVM. * @see System#inheritedChannel() diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index ce4cf601c9..22b8377deb 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -86,6 +86,8 @@ public class Main public static String join(Collection<?> objs, String delim) { + if (objs==null) + return ""; StringBuilder str = new StringBuilder(); boolean needDelim = false; for (Object obj : objs) @@ -392,17 +394,45 @@ public class Main } boolean transitive = module.isEnabled() && (module.getSources().size() == 0); - boolean hasDefinedDefaults = module.getDefaultConfig().size() > 0; - - // If it is not enabled or is transitive with ini template lines or toplevel and doesn't exist - if (!module.isEnabled() || (transitive && (hasDefinedDefaults || module.hasLicense()) ) || (topLevel && !FS.exists(startd_ini) && !appendStartIni)) + boolean buildIni=false; + if (module.isEnabled()) + { + // is it an explicit request to create an ini file? + if (topLevel && !FS.exists(startd_ini) && !appendStartIni) + buildIni=true; + + // else is it transitive + else if (transitive) + { + // do we need an ini anyway? + if (module.hasDefaultConfig() || module.hasLicense()) + buildIni=true; + else + StartLog.info("%-15s initialised transitively",name); + } + + // else must be initialized explicitly + else + { + for (String source : module.getSources()) + StartLog.info("%-15s initialised in %s",name,baseHome.toShortForm(source)); + } + } + else + { + buildIni=true; + } + + + // If we need an ini + if (buildIni) { if (module.hasLicense()) { - System.err.printf("%nModule %s LICENSE%n",module.getName()); - System.err.printf("This module is not provided by the Eclipse Foundation!%n"); - System.err.printf("It contains software not covered by the Eclipse Public License%n"); - System.err.printf("The software has not been audited for compliance with its license%n"); + System.err.printf("%nModule %s:%n",module.getName()); + System.err.printf(" + contains software not provided by the Eclipse Foundation!%n"); + System.err.printf(" + contains software not covered by the Eclipse Public License!%n"); + System.err.printf(" + has not been audited for compliance with its license%n"); System.err.printf("%n"); for (String l : module.getLicense()) System.err.printf(" %s%n",l); @@ -484,14 +514,6 @@ public class Main } } } - else if (FS.exists(startd_ini)) - { - StartLog.info("%-15s initialised in %s",name,short_startd_ini); - } - else - { - StartLog.info("%-15s initialised transitively",name); - } // Also list other places this module is enabled for (String source : module.getSources()) diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java index 3b1f79e227..a55fd9e77b 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -265,6 +265,12 @@ public class Modules implements Iterable<Module> } } + public void enable(String name) throws IOException + { + List<String> empty = Collections.emptyList(); + enable(name,empty); + } + public void enable(String name, List<String> sources) throws IOException { if (name.contains("*")) @@ -310,9 +316,14 @@ public class Modules implements Iterable<Module> private void enableModule(Module module, List<String> sources) throws IOException { + // Always add the sources + if (sources != null) + module.addSources(sources); + + // If already enabled, nothing else to do if (module.isEnabled()) { - // already enabled, skip + StartLog.debug("Enabled module: %s (via %s)",module.getName(),Main.join(sources,", ")); return; } @@ -320,10 +331,6 @@ public class Modules implements Iterable<Module> module.setEnabled(true); args.parseModule(module); module.expandProperties(args.getProperties()); - if (sources != null) - { - module.addSources(sources); - } // enable any parents that haven't been enabled (yet) Set<String> parentNames = new HashSet<>(); @@ -349,7 +356,7 @@ public class Modules implements Iterable<Module> } if (parent != null) { - enableModule(parent,sources); + enableModule(parent,null); } } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java index 79629eb1ec..1e81258a08 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java @@ -479,7 +479,10 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo @Override public void dump(Appendable out, String indent) throws IOException { - out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle ? " IDLE" : "").append('\n'); + out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle ? " IDLE" : ""); + if (thread.getPriority()!=Thread.NORM_PRIORITY) + out.append(" prio="+thread.getPriority()); + out.append('\n'); if (!idle) ContainerLifeCycle.dump(out, indent, Arrays.asList(trace)); } @@ -493,7 +496,8 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo } else { - dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : "")); + int p=thread.getPriority(); + dump.add(thread.getId() + " " + thread.getName() + " " + thread.getState() + " @ " + (trace.length > 0 ? trace[0] : "???") + (idle ? " IDLE" : "")+ (p==Thread.NORM_PRIORITY?"":(" prio="+p))); } } diff --git a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini b/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini deleted file mode 100644 index 9607fd29f9..0000000000 --- a/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini +++ /dev/null @@ -1,6 +0,0 @@ -# -# HTTP connector -# ---module=http -jetty.port=8080 - |