Jetty:以编程方式停止会导致“1 个线程无法停止”

发布于 2024-10-11 04:07:30 字数 2947 浏览 2 评论 0原文

我有一个嵌入式 Jetty 6.1.26 实例。 我想通过发送到 /shutdown 的 HTTP GET 来关闭它。 所以我创建了一个 JettyShutdownServlet:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

 resp.setStatus(202, "Shutting down.");
 resp.setContentType("text/plain");
 ServletOutputStream os = resp.getOutputStream();
 os.println("Shutting down.");
 os.close();
 resp.flushBuffer();

 // Stop the server.
 try {
    log.info("Shutting down the server...");
    server.stop();
 } catch (Exception ex) {
    log.error("Error when stopping Jetty server: "+ex.getMessage(), ex);
 }

但是,当我发送请求时,Jetty 不会停止 - 一个线程一直挂在 org.mortbay.thread.QueuedThreadPool 上,与 < code>this.wait():

   // We are idle
   // wait for a dispatched job
   synchronized (this)
   {
       if (_job==null)
          this.wait(getMaxIdleTimeMs());
       job=_job;
       _job=null;
   }

...

2011-01-10 20:14:20,375 INFO  org.mortbay.log jetty-6.1.26
2011-01-10 20:14:34,756 INFO  org.mortbay.log Started [email protected]:17283
2011-01-10 20:25:40,006 INFO  org.jboss.qa.mavenhoe.MavenHoeApp Shutting down the server...
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown [email protected]:17283
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown org.mortbay.jetty.servlet.Context@1672bbb{/,null}
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown org.mortbay.jetty.webapp.WebAppContext@18d30fb{/jsp,file:/home/ondra/work/Mavenhoe/trunk/target/classes/org/jboss/qa/mavenhoe/web/jsp}
2011-01-10 20:25:43,007 INFO  org.mortbay.log Stopped [email protected]:17283
2011-01-10 20:25:43,009 WARN  org.mortbay.log 1 threads could not be stopped
2011-01-10 20:26:43,010 INFO  org.mortbay.log Shutdown hook executing
2011-01-10 20:26:43,011 INFO  org.mortbay.log Shutdown hook complete

它正好阻塞一分钟,然后关闭。 我添加了 Graceful shutdown,它应该允许我从 servlet 关闭服务器;但是,正如您从日志中看到的那样,它不起作用。

我是这样解决的:

Server server = new Server( PORT );
server.setGracefulShutdown( 3000 );
server.setStopAtShutdown(true);
...
server.start();

if( server.getThreadPool() instanceof QueuedThreadPool ){
   ((QueuedThreadPool) server.getThreadPool()).setMaxIdleTimeMs( 2000 );
}

setMaxIdleTimeMs()需要在start()之后调用,因为threadPool是在start()中创建的>。但是,线程已经创建并正在等待,因此仅在所有线程至少使用一次后才适用。

除了中断所有线程或 System.exit() 等一些可怕的事情之外,我不知道还能做什么。

有什么想法吗?有什么好的办法吗?

I have an embedded Jetty 6.1.26 instance.
I want to shut it down by HTTP GET sent to /shutdown.
So I created a JettyShutdownServlet:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

 resp.setStatus(202, "Shutting down.");
 resp.setContentType("text/plain");
 ServletOutputStream os = resp.getOutputStream();
 os.println("Shutting down.");
 os.close();
 resp.flushBuffer();

 // Stop the server.
 try {
    log.info("Shutting down the server...");
    server.stop();
 } catch (Exception ex) {
    log.error("Error when stopping Jetty server: "+ex.getMessage(), ex);
 }

However, when I send the request, Jetty does not stop - a thread keeps hanging in org.mortbay.thread.QueuedThreadPool on the line with this.wait():

   // We are idle
   // wait for a dispatched job
   synchronized (this)
   {
       if (_job==null)
          this.wait(getMaxIdleTimeMs());
       job=_job;
       _job=null;
   }

...

2011-01-10 20:14:20,375 INFO  org.mortbay.log jetty-6.1.26
2011-01-10 20:14:34,756 INFO  org.mortbay.log Started [email protected]:17283
2011-01-10 20:25:40,006 INFO  org.jboss.qa.mavenhoe.MavenHoeApp Shutting down the server...
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown [email protected]:17283
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown org.mortbay.jetty.servlet.Context@1672bbb{/,null}
2011-01-10 20:25:40,006 INFO  org.mortbay.log Graceful shutdown org.mortbay.jetty.webapp.WebAppContext@18d30fb{/jsp,file:/home/ondra/work/Mavenhoe/trunk/target/classes/org/jboss/qa/mavenhoe/web/jsp}
2011-01-10 20:25:43,007 INFO  org.mortbay.log Stopped [email protected]:17283
2011-01-10 20:25:43,009 WARN  org.mortbay.log 1 threads could not be stopped
2011-01-10 20:26:43,010 INFO  org.mortbay.log Shutdown hook executing
2011-01-10 20:26:43,011 INFO  org.mortbay.log Shutdown hook complete

It blocks for exactly one minute, then shuts down.
I've added the Graceful shutdown, which should allow me to shut the server down from a servlet; However, it does not work as you can see from the log.

I've solved it this way:

Server server = new Server( PORT );
server.setGracefulShutdown( 3000 );
server.setStopAtShutdown(true);
...
server.start();

if( server.getThreadPool() instanceof QueuedThreadPool ){
   ((QueuedThreadPool) server.getThreadPool()).setMaxIdleTimeMs( 2000 );
}

setMaxIdleTimeMs() needs to be called after the start(), becase the threadPool is created in start(). However, the threads are already created and waiting, so it only applies after all threads are used at least once.

I don't know what else to do except some awfulness like interrupting all threads or System.exit().

Any ideas? Is there a good way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧城空念 2024-10-18 04:07:30

Graceful 不会做您想象的那样 - 它允许服务器正常关闭,但它不允许允许您从 servlet 内部关闭。

问题如您链接到的邮件列表帖子中所述 - 您正在尝试停止服务器,同时仍在服务器内部处理连接。

您应该尝试将 servlet 的实现更改为:

// Stop the server.
new Thread()
{
   public void run() {
     try {
        log.info("Shutting down the server...");
        server.stop();
        log.info("Server has stopped.");
     } catch (Exception ex) {
        log.error("Error when stopping Jetty server: "+ex.getMessage(), ex);
     }
   }
}.start();

这样 servlet 就可以在服务器关闭时完成处理,并且不会阻止关闭过程。

Graceful doesn't do what you think it does - it allows the server to shutdown gracefully, but it does not allow you to shutdown from inside a servlet.

The problem is as described in the mailing-list post you linked to - you're trying to stop the server, while you're still processing a connection inside the server.

You should try changing your servlet's implementation to:

// Stop the server.
new Thread()
{
   public void run() {
     try {
        log.info("Shutting down the server...");
        server.stop();
        log.info("Server has stopped.");
     } catch (Exception ex) {
        log.error("Error when stopping Jetty server: "+ex.getMessage(), ex);
     }
   }
}.start();

That way the servlet can finished processing while the server is shutting down, and will not hold up the shutdown process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文