From 69390954dc15acc389479b647f290da121ccc9de Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 29 Aug 2014 15:36:19 +1000 Subject: [PATCH] 435322 acceptor and selector configuration/priority --- .../org/eclipse/jetty/io/SelectorManager.java | 35 ++++++++++++ .../src/main/config/etc/jetty-http.xml | 4 ++ .../src/main/config/etc/jetty-https.xml | 44 ++++++++------- jetty-server/src/main/config/modules/http.mod | 17 ++++-- jetty-server/src/main/config/modules/ssl.mod | 21 +++++--- .../jetty/server/AbstractConnector.java | 41 ++++++++++++-- .../eclipse/jetty/server/ServerConnector.java | 39 ++++++++++++++ .../java/org/eclipse/jetty/start/Main.java | 54 +++++++++++++------ .../java/org/eclipse/jetty/start/Modules.java | 19 ++++--- .../jetty/util/thread/QueuedThreadPool.java | 8 ++- .../main/config/demo-base/start.d/http.ini | 6 --- 11 files changed, 221 insertions(+), 67 deletions(-) delete mode 100644 tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/start.d/http.ini 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 0e6fd889da6..57282593318 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. + *

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

+ * @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 c3f74f3e668..75012f36af2 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 @@ + + @@ -35,6 +37,8 @@ + + diff --git a/jetty-server/src/main/config/etc/jetty-https.xml b/jetty-server/src/main/config/etc/jetty-https.xml index 419f8d19ee6..a019cb90e7b 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 @@ - - - - - http/1.1 - - - - - - - - - - - - - - - + + + + + + + http/1.1 + + + + + + + + + + + + + + + + + diff --git a/jetty-server/src/main/config/modules/http.mod b/jetty-server/src/main/config/modules/http.mod index 8740af3c7b8..dc34bc3cb98 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 449f58104fb..ef471929f30 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 3106eec2575..860799442fb 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. + *

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

+ * @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 f4da30c004e..87daedf02bc 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. + *

Construct a ServerConnector with a private instance of {@link HttpConnectionFactory} as the only factory.

+ * @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. + *

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

+ * @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 ce4cf601c9c..22b8377deb1 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 3b1f79e2275..a55fd9e77bb 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 } } + public void enable(String name) throws IOException + { + List empty = Collections.emptyList(); + enable(name,empty); + } + public void enable(String name, List sources) throws IOException { if (name.contains("*")) @@ -310,9 +316,14 @@ public class Modules implements Iterable private void enableModule(Module module, List 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.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 parentNames = new HashSet<>(); @@ -349,7 +356,7 @@ public class Modules implements Iterable } 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 79629eb1ec3..1e81258a083 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 9607fd29f92..00000000000 --- 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 -