2011-01-10 61 views
6

我有一個嵌入式Jetty 6.1.26實例。 我想通過HTTP GET將它關閉發送到/shutdown。 所以我創建了一個JettyShutdownServlet碼頭:以編程方式停止導致「1線程無法停止」

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

然而,當我發送請求,碼頭不停止 - 線程一直掛在org.mortbay.thread.QueuedThreadPool上的線與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 [email protected]{/,null} 
2011-01-10 20:25:40,006 INFO org.mortbay.log Graceful shutdown [email protected]{/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()需要becase的線程池在start()創建start()後調用。但是,這些線程已經創建並正在等待,因此它僅適用於所有線程至少使用過一次之後。

我不知道還有什麼要做,除了像打斷所有線程或System.exit()一些可怕的事情。

任何想法?有沒有好的方法?

感謝, Ondra

+0

我發現似乎討論了這個問題 - http://osdir.com/ml/java.jetty.general/2003-10/msg00074.html - 但是,仍然感謝關機應該處理這個國際海事組織。 – 2011-01-10 19:54:41

回答

11

優美沒有做什麼你認爲它 - 它允許服務器安全關機,但它允許你關閉從一個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可以完成處理,並且不會撐起關機過程。

+0

這聽起來不錯,我會嘗試。謝謝。 – 2011-01-11 18:37:02