Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimone Bordet2013-03-01 14:19:51 +0000
committerSimone Bordet2013-03-01 14:19:51 +0000
commite6fed09129e628f842102a4c73252b1a01809427 (patch)
tree91ea6de8c5edacda588beab5cdcb9d050c2b0167 /jetty-server
parent2feafb9a9726dbac73e0f42852573b82c988ad6a (diff)
downloadorg.eclipse.jetty.project-e6fed09129e628f842102a4c73252b1a01809427.tar.gz
org.eclipse.jetty.project-e6fed09129e628f842102a4c73252b1a01809427.tar.xz
org.eclipse.jetty.project-e6fed09129e628f842102a4c73252b1a01809427.zip
402075 - Massive old gen growth when hit by lots of non persistent connections.
Replaced usages of TimerScheduler with ScheduledExecutorScheduler.
Diffstat (limited to 'jetty-server')
-rw-r--r--jetty-server/src/main/config/etc/jetty.xml14
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java18
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java76
3 files changed, 54 insertions, 54 deletions
diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml
index 06dc9e7131..9836464f7c 100644
--- a/jetty-server/src/main/config/etc/jetty.xml
+++ b/jetty-server/src/main/config/etc/jetty.xml
@@ -14,7 +14,7 @@
<!-- java -jar start.jar -? -->
<!-- =============================================================== -->
-<!-- =============================================================== -->
+<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
@@ -49,13 +49,13 @@
<Set name="detailedDump">false</Set>
</New>
</Arg>
-
+
<!-- =========================================================== -->
<!-- Add shared Scheduler instance -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
- <New class="org.eclipse.jetty.util.thread.TimerScheduler"/>
+ <New class="org.eclipse.jetty.util.thread.ScheduledExecutorScheduler"/>
</Arg>
</Call>
@@ -82,14 +82,14 @@
<Set name="responseHeaderSize">8192</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">false</Set>
-
- <!-- Uncomment to enable handling of X-Forwarded- style headers
+
+ <!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->
</New>
-
+
<!-- =========================================================== -->
<!-- Set the default handler structure for the Server -->
@@ -99,7 +99,7 @@
<!-- DefaultHandler, which handles any requests not handled by -->
<!-- the context handlers. -->
<!-- Other handlers may be added to the "Handlers" collection, -->
- <!-- for example the jetty-requestlog.xml file adds the -->
+ <!-- for example the jetty-requestlog.xml file adds the -->
<!-- RequestLogHandler after the default handler -->
<!-- =========================================================== -->
<Set name="handler">
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 ca40a390df..bcc13aa3cd 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
@@ -48,8 +48,8 @@ import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
-import org.eclipse.jetty.util.thread.TimerScheduler;
/**
* <p>An abstract implementation of {@link Connector} that provides a {@link ConnectionFactory} mechanism
@@ -63,7 +63,7 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* </li>
* <li>The {@link Scheduler} service is used to monitor the idle timeouts of all connections and is also made available
* to the connections to time such things as asynchronous request timeouts. The default is to use a new
- * {@link TimerScheduler} instance.
+ * {@link ScheduledExecutorScheduler} instance.
* </li>
* <li>The {@link ByteBufferPool} service is made available to all connections to be used to acquire and release
* {@link ByteBuffer} instances from a pool. The default is to use a new {@link ArrayByteBufferPool} instance.
@@ -151,12 +151,12 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
private long _idleTimeout = 30000;
private String _defaultProtocol;
private ConnectionFactory _defaultConnectionFactory;
-
+
/**
* @param server The server this connector will be added to. Must not be null.
* @param executor An executor for this connector or null to use the servers executor
- * @param scheduler A scheduler for this connector or null to either a {@link Scheduler} set as a server bean or if none set, then a new {@link TimerScheduler} instance.
+ * @param scheduler A scheduler for this connector or null to either a {@link Scheduler} set as a server bean or if none set, then a new {@link ScheduledExecutorScheduler} instance.
* @param pool A buffer pool for this connector or null to either a {@link ByteBufferPool} set as a server bean or none set, the new {@link ArrayByteBufferPool} instance.
* @param acceptors the number of acceptor threads to use, or 0 for a default value.
* @param factories The Connection Factories to use.
@@ -173,7 +173,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
_executor=executor!=null?executor:_server.getThreadPool();
if (scheduler==null)
scheduler=_server.getBean(Scheduler.class);
- _scheduler=scheduler!=null?scheduler:new TimerScheduler();
+ _scheduler=scheduler!=null?scheduler:new ScheduledExecutorScheduler();
if (pool==null)
pool=_server.getBean(ByteBufferPool.class);
_byteBufferPool = pool!=null?pool:new ArrayByteBufferPool();
@@ -479,9 +479,9 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
}
}
-
-
-
+
+
+
// protected void connectionOpened(Connection connection)
// {
// _stats.connectionOpened();
@@ -512,7 +512,7 @@ public abstract class AbstractConnector extends ContainerLifeCycle implements Co
{
_endpoints.add(endp);
}
-
+
protected void onEndPointClosed(EndPoint endp)
{
_endpoints.remove(endp);
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
index d4a1dbb029..3749e04057 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java
@@ -32,9 +32,9 @@ import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
+import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.ThreadPool;
-import org.eclipse.jetty.util.thread.TimerScheduler;
/* ------------------------------------------------------------ */
@@ -42,7 +42,7 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* <p>An instance of this class will monitor all the connectors of a server (or a set of connectors
* configured with {@link #setMonitoredConnectors(Collection)}) for a low resources state.
* Low resources can be detected by:<ul>
- * <li>{@link ThreadPool#isLowOnThreads()} if {@link Connector#getExecutor()} is
+ * <li>{@link ThreadPool#isLowOnThreads()} if {@link Connector#getExecutor()} is
* an instance of {@link ThreadPool} and {@link #setMonitorThreads(boolean)} is true.<li>
* <li>If {@link #setMaxMemory(long)} is non zero then low resources is detected if the JVMs
* {@link Runtime} instance has {@link Runtime#totalMemory()} minus {@link Runtime#freeMemory()}
@@ -51,11 +51,11 @@ import org.eclipse.jetty.util.thread.TimerScheduler;
* of connections exceeds {@link #getMaxConnections()}</li>
* </ul>
* </p>
- * <p>Once low resources state is detected, the cause is logged and all existing connections returned
- * by {@link Connector#getConnectedEndPoints()} have {@link EndPoint#setIdleTimeout(long)} set
- * to {@link #getLowResourcesIdleTimeout()}. New connections are not affected, however if the low
- * resources state persists for more than {@link #getMaxLowResourcesTime()}, then the
- * {@link #getLowResourcesIdleTimeout()} to all connections again. Once the low resources state is
+ * <p>Once low resources state is detected, the cause is logged and all existing connections returned
+ * by {@link Connector#getConnectedEndPoints()} have {@link EndPoint#setIdleTimeout(long)} set
+ * to {@link #getLowResourcesIdleTimeout()}. New connections are not affected, however if the low
+ * resources state persists for more than {@link #getMaxLowResourcesTime()}, then the
+ * {@link #getLowResourcesIdleTimeout()} to all connections again. Once the low resources state is
* cleared, the idle timeout is reset to the connector default given by {@link Connector#getIdleTimeout()}.
* </p>
*/
@@ -76,44 +76,44 @@ public class LowResourceMonitor extends AbstractLifeCycle
private String _cause;
private String _reasons;
private long _lowStarted;
-
-
+
+
private final Runnable _monitor = new Runnable()
{
@Override
public void run()
- {
+ {
if (isRunning())
{
monitor();
_scheduler.schedule(_monitor,_period,TimeUnit.MILLISECONDS);
}
- }
+ }
};
-
+
public LowResourceMonitor(@Name("server") Server server)
{
_server=server;
}
-
+
@ManagedAttribute("Are the monitored connectors low on resources?")
public boolean isLowOnResources()
{
return _low.get();
}
-
+
@ManagedAttribute("The reason(s) the monitored connectors are low on resources")
public String getLowResourcesReasons()
{
return _reasons;
}
-
+
@ManagedAttribute("Get the timestamp in ms since epoch that low resources state started")
public long getLowResourcesStarted()
{
return _lowStarted;
}
-
+
@ManagedAttribute("The monitored connectors. If null then all server connectors are monitored")
public Collection<Connector> getMonitoredConnectors()
{
@@ -140,7 +140,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
/**
- * @param periodMS The period in ms to monitor for low resources
+ * @param periodMS The period in ms to monitor for low resources
*/
public void setPeriod(int periodMS)
{
@@ -154,8 +154,8 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
/**
- * @param monitorThreads If true, check connectors executors to see if they are
- * {@link ThreadPool} instances that are low on threads.
+ * @param monitorThreads If true, check connectors executors to see if they are
+ * {@link ThreadPool} instances that are low on threads.
*/
public void setMonitorThreads(boolean monitorThreads)
{
@@ -222,14 +222,14 @@ public class LowResourceMonitor extends AbstractLifeCycle
protected void doStart() throws Exception
{
_scheduler = _server.getBean(Scheduler.class);
-
+
if (_scheduler==null)
{
_scheduler=new LRMScheduler();
_scheduler.start();
}
super.doStart();
-
+
_scheduler.schedule(_monitor,_period,TimeUnit.MILLISECONDS);
}
@@ -240,24 +240,24 @@ public class LowResourceMonitor extends AbstractLifeCycle
_scheduler.stop();
super.doStop();
}
-
+
protected Connector[] getMonitoredOrServerConnectors()
{
if (_monitoredConnectors!=null && _monitoredConnectors.length>0)
return _monitoredConnectors;
return _server.getConnectors();
}
-
+
protected void monitor()
{
String reasons=null;
String cause="";
int connections=0;
-
+
for(Connector connector : getMonitoredOrServerConnectors())
{
connections+=connector.getConnectedEndPoints().size();
-
+
Executor executor = connector.getExecutor();
if (executor instanceof ThreadPool)
{
@@ -269,21 +269,21 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
}
}
-
+
if (_maxConnections>0 && connections>_maxConnections)
{
reasons=low(reasons,"Max Connections exceeded: "+connections+">"+_maxConnections);
cause+="C";
}
-
+
long memory=Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
if (_maxMemory>0 && memory>_maxMemory)
{
reasons=low(reasons,"Max memory exceeded: "+memory+">"+_maxMemory);
cause+="M";
}
-
-
+
+
if (reasons!=null)
{
// Log the reasons if there is any change in the cause
@@ -292,7 +292,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
LOG.warn("Low Resources: {}",reasons);
_cause=cause;
}
-
+
// Enter low resources state?
if (_low.compareAndSet(false,true))
{
@@ -300,12 +300,12 @@ public class LowResourceMonitor extends AbstractLifeCycle
_lowStarted=System.currentTimeMillis();
setLowResources();
}
-
+
// Too long in low resources state?
if (_maxLowResourcesTime>0 && (System.currentTimeMillis()-_lowStarted)>_maxLowResourcesTime)
setLowResources();
}
- else
+ else
{
if (_low.compareAndSet(true,false))
{
@@ -316,7 +316,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
}
}
}
-
+
protected void setLowResources()
{
for(Connector connector : getMonitoredOrServerConnectors())
@@ -325,7 +325,7 @@ public class LowResourceMonitor extends AbstractLifeCycle
endPoint.setIdleTimeout(_lowResourcesIdleTimeout);
}
}
-
+
protected void clearLowResources()
{
for(Connector connector : getMonitoredOrServerConnectors())
@@ -334,16 +334,16 @@ public class LowResourceMonitor extends AbstractLifeCycle
endPoint.setIdleTimeout(connector.getIdleTimeout());
}
}
-
+
private String low(String reasons, String newReason)
{
if (reasons==null)
return newReason;
return reasons+", "+newReason;
}
-
-
- private static class LRMScheduler extends TimerScheduler
+
+
+ private static class LRMScheduler extends ScheduledExecutorScheduler
{
}
}

Back to the top