435322 acceptor and selector configuration/priority

This commit is contained in:
Greg Wilkins 2014-08-29 15:36:19 +10:00
parent eee2ba206e
commit 69390954dc
11 changed files with 221 additions and 67 deletions

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -114,6 +114,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.
* <p>Construct a Server Connector with the passed Connection factories.</p>
@ -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()

View File

@ -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;
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;
// 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))
// 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())

View File

@ -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);
}
}
}

View File

@ -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)));
}
}

View File

@ -1,6 +0,0 @@
#
# HTTP connector
#
--module=http
jetty.port=8080