Reputation: 2177
I've dug through the Jetty documentation trying to find out how to properly configure an embedded Jetty to shut down gracefully, but I found it lacking.
The examples in the documentation inconsequently use setStopAtShutdown(true)
. However, there is no JavaDoc or explanation why this should be done. As far as I can tell, the default value is set to false.
Additionally, the setGracefulShutdown()
method changed to setStopTimeout()
it seems, but this is not documented either.
So these are my questions:
Edit: After some trial and error; discovered that setStopAtShutdown(true) is required if you want to have Jetty signal a shutdown event to any listeners such as Spring's ContextLoaderListener.
Upvotes: 15
Views: 16011
Reputation: 7847
The graceful shutdown procedure requests each worker thread to shut down (i.e. finish processing the current request, then don't accept any new requests and exit). It then waits for a bit (configurable via the timeout), and if any threads remain, it kills them forcefully. This can happen because the thread is taking a long time to process a request, for example, or because of a deadlock. If you keep the default value of 30 seconds, it might take a little more than 30 seconds for the application to exit. Reducing the value of the timeout will give you a faster shutdown time, but at the expense of potentially killing threads that were busy processing legitimate, active requests.
Upvotes: 13
Reputation: 895
The default stopAtShutdown
seems to be true, see at http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-server/src/main/config/etc/jetty.xml?h=jetty-9.1.x, the timeout is also there, 5 seconds:
<Set name="stopAtShutdown">true</Set>
<Set name="stopTimeout">5000</Set>
Additionally, you may configure a LifeCycle.Listener for more specific cases, e.g., I use one to remove a pid file (among other things) when shutting down the server, I attach the listener in the Connector using addLifeCycleListener on the ServerConnector, in jetty xml, it looks like:
<Configure id="Server" class="org.eclipse.jetty.server.Server">
...
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
...
<Call name="addLifeCycleListener">
<Arg>
<New class="com.acme.jetty.ConnectorListener"/>
</Arg>
</Call>
and ConnectorListener.java would begin with something like:
package com.acme.jetty;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
public class ConnectorListener implements LifeCycle.Listener {
private static final Logger LOG = Log.getLogger(ConnectorListener.class);
...
public void lifeCycleStopped(LifeCycle event) {
LOG.debug("lifeCycleStopped()");
}
I know this does not address your questions directly, but maybe you could provide us more information.
Upvotes: 2