简体   繁体   English

Spring + Jetty:优雅的关机

[英]Spring + Jetty: graceful shutdown

Objective: Having Spring web application with an embedded Jetty, I'd like to shutdown/restart the application gracefully. 目标:使用嵌入式Jetty的Spring Web应用程序,我想优雅地关闭/重新启动应用程序。
Here's the EmbeddedServletContainerFactory bean (I'll add the omitted code if needed): 这是EmbeddedServletContainerFactory bean(如果需要,我将添加省略的代码):

@Bean
public EmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
    JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
    factory.addServerCustomizers(server -> {

        server.setStopAtShutdown(false);

        /*
         * StatisticsHandler has to be added for graceful shutdown to work (see
         * https://github.com/eclipse/jetty.project/issues/1549#issuecomment-301102535)
         */
        StatisticsHandler statisticsHandler = new StatisticsHandler();
        statisticsHandler.setHandler(server.getHandler());
        server.setHandler(statisticsHandler);
    });
    return factory;
}

and here's our shutdown signal handler: 这是我们的关机信号处理程序:

@Component
public class ShutdownSignalHandler {

    @Value("${shutdown.signalType:TERM}")
    private String signal;

    @Autowired
    private ConfigurableApplicationContext context;

    @Autowired
    private Server jetty; 

    @PostConstruct
    public void init() {
        Signal.handle(new Signal(signal), this::signalHandler);
    }

    private void signalHandler(Signal signal) {
        jetty.stop();
        context.close();
    }
}

Question: having the above configuration, every time I restart the application via TERM signal, I see a lot of 503 entries in apache_access log (almost all of them happen while jetty.stop is being executed). 问题:具有上述配置,每次通过TERM信号重启应用程序时,我都会在apache_access日志中看到很多503条目(几乎所有这些jetty.stop都在执行jetty.stop发生)。
Any idea how/why it happens and what the resolution is? 知道它是如何/为什么发生以及解决方案是什么?

Why/how does it happen? 为什么/如何发生? Well it's the default behavior of Jetty: First, Jetty close the network connectors to stop accepting new connections and then wait for active request to be process. 这是Jetty的默认行为:首先,Jetty关闭网络连接器以停止接受新连接,然后等待活动请求进行处理。 But the catch is new requests might be sent to Jetty over already-established connections (those which are connected before shutdown process starts). 但问题是新的请求可能会通过已建立的连接(在关闭进程启动之前连接的连接)发送给Jetty。
Solutions: Send retry response for new requests sent over open connections. 解决方案:通过打开的连接发送新请求的重试响应。 We customized StatisticsHandler so that, during stop process instead of handling request with 503 , it handles them with 307 Connection: close, Location: <original-url> . 我们定制了StatisticsHandler以便在停止过程中而不是使用503处理请求时,它使用307 Connection: close, Location: <original-url>来处理它们。

UPDATE: what we did was to change the implementation of the handle method of the StatisticsHandler class (Look for Change this line! comment): 更新:我们所做的是更改StatisticsHandler类的handle方法的实现(查找Change this line!注释):

@Override
public void handle(String path, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
    ...
    try
    {
        Handler handler = getHandler();
        if (handler!=null && _shutdown.get()==null && isStarted())
            handler.handle(path, baseRequest, request, response);
        else if (baseRequest.isHandled())
        {
            if (_wrapWarning.compareAndSet(false,true))
                LOG.warn("Bad statistics configuration. Latencies will be incorrect in {}",this);
        }
        else
        {
            baseRequest.setHandled(true);
            response.sendError(HttpStatus.SERVICE_UNAVAILABLE_503); // Change this line!
        }
    }
    finally
    {
        ...
    }
}

503 - Service Unavailable 503服务不可用

Apache can't a get a response when proxying the request to the servlet container because, there is no servlet container listening on the host:port specified in the proxy configuration. 在将请求代理到servlet容器时,Apache无法获得响应,因为在代理配置中指定的host:port上没有监听servlet容器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM