Jetty:以编程方式停止导致“1个线程无法停止” [英] Jetty: Stopping programatically causes "1 threads could not be stopped"

查看:223
本文介绍了Jetty:以编程方式停止导致“1个线程无法停止”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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);
 }

然而,当我发送请求时,Jetty不会停止 - 一个线程保持挂在 org.mortbay.thread.QueuedThreadPool 上的 this.wait()

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 SocketConnector@0.0.0.0: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 SocketConnector@0.0.0.0: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 SocketConnector@0.0.0.0: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关闭服务器;但是,它从日志中看不到。

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()需要在 start()之后调用,因为threadPool是在 start()中创建的。但是,线程已经创建并等待,所以它只适用于所有线程至少使用一次之后。

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.

除了一些可怕之外,我不知道还能做什么比如打断所有线程或 System.exit()

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?

推荐答案

优雅不符合您的想法 - 它允许服务器正常关闭,但它不允许你从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.

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

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();

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

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

这篇关于Jetty:以编程方式停止导致“1个线程无法停止”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆