Tomcat在关闭时是否会过早销毁ServletContext?

时间:2018-11-21 23:09:27

标签: java tomcat

在关闭时,我希望Tomcat停止接受新请求(并且确实如此!),并成功完成正在进行的请求。不幸的是,ServletContext(Servlet.destroyServletContextListener.contextDestroyed,...)在完成正在进行的请求之前已被销毁。 这些依赖ServletContext的正在进行的请求将失败,并可能损坏数据!仅在处理正在进行的请求之后,才应删除上下文。

深入研究代码,org.apache.catalina.core.StandardService.stopInternal方法确实揭示了ServletContext在关闭(engine.stop()语句)请求的线程池(ThreadPoolExecutor)之前已被销毁(connector.stop()语句)。

我确实找到了StandardContext.unloadDelay参数(容器等待servlet卸载的毫秒数。如果未指定,默认值为2000毫秒。)这可能是解决方案...

您知道如何以不同的方式解决此问题吗?

如何复制:

@WebServlet(name = "StartStopServlet", displayName = "StartStopServlet", urlPatterns = "/execute")
public class StartStopServlet extends javax.servlet.http.HttpServlet {
    private ExpensiveResource resource = null;

    @Override
    public void init() throws ServletException {
        System.out.println("----> initializing StartStopServlet ...");
        super.init();

        resource = new ExpensiveResource();
        resource.connect();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // simulating time consuming operation before invoking ExpensiveService
        System.out.println("----> preparing parameters for ExpensiveResource call. It will take about 6 secs");

        // Now is the time to stop Tomcat: invoke shutdown.sh (or shutdown.bat)

        try {
            Thread.currentThread().sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // produces NullPointerException if ServletContext is destroyed
        Model result = resource.doWork();

        // Preparing response...
    }

    @Override
    public void destroy() {
        System.out.println("----> destroying StartStopServlet ...");
        super.destroy();

        resource.disconnect();
        resource = null;
    }
}
resource.doWork()方法之后调用

destroy()语句。

0 个答案:

没有答案