2011-01-10 27 views
6

Tôi có một phiên bản Jetty 6.1.26 được nhúng. Tôi muốn tắt nó bằng HTTP GET được gửi đến /shutdown. Vì vậy, tôi đã tạo ra một JettyShutdownServlet:Cầu tàu: Dừng theo chương trình gây ra "1 luồng không thể dừng lại"

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

Tuy nhiên, khi tôi gửi yêu cầu, Jetty không chỉ dừng lại - a thread tiếp tục treo trong org.mortbay.thread.QueuedThreadPool trên phù hợp với 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 

Nó chặn chính xác một phút, sau đó tắt. Tôi đã thêm chức năng tắt Graceful, cho phép tôi tắt máy chủ từ một servlet; Tuy nhiên, nó không hoạt động như bạn thấy từ nhật ký.

Tôi đã giải quyết nó theo cách này:

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

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

setMaxIdleTimeMs() cần phải được gọi sau khi start(), becase ThreadPool được tạo ra trong start(). Tuy nhiên, các chủ đề đã được tạo và chờ đợi, vì vậy nó chỉ áp dụng sau khi tất cả các chủ đề được sử dụng ít nhất một lần.

Tôi không biết phải làm gì khác ngoại trừ một số khủng khiếp như làm gián đoạn tất cả các chủ đề hoặc System.exit().

Bất kỳ ý tưởng nào? Có cách nào tốt không?

Cảm ơn, Ondra

+0

Tôi đã tìm thấy những gì dường như để thảo luận vấn đề - http://osdir.com/ml/java.jetty.general/2003-10/msg00074.html - tuy nhiên, việc tắt máy biết ơn phải xử lý IMO này. –

Trả lời

11

Graceful không làm những gì bạn nghĩ nó - nó cho phép các máy chủ để tắt máy một cách duyên dáng, nhưng nó không cho phép bạn tắt máy từ bên trong một servlet.

Sự cố được mô tả trong bài đăng danh sách gửi thư mà bạn đã liên kết đến - bạn đang cố dừng máy chủ trong khi vẫn đang xử lý kết nối bên trong máy chủ.

Bạn nên cố gắng thay đổi thực hiện của servlet của bạn để:

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

Bằng cách đó các servlet có thể hoàn tất xử lý khi máy chủ được tắt, và sẽ không giữ quá trình tắt máy.

+0

Nghe hay đấy, tôi sẽ thử. Cảm ơn. –

+1

Giải pháp này hoạt động. Tuy nhiên, tôi đã phải thêm 'Thread.sleep()' để ngăn chặn sự kiện tương tự - luồng được thực hiện quá sớm. Vì vậy, tôi tự hỏi làm thế nào để chặn nó cho đến khi chuỗi yêu cầu kết thúc. 'join()' không hoạt động kể từ khi thread quay trở lại pool. –

+1

@Ondra Žižka Không chắc chắn nếu điều này vẫn còn có liên quan, nhưng xin xem xét một câu trả lời tại http://stackoverflow.com/questions/5719159/programmatic-jetty-shutdown/9704012#9704012 – 01es

Các vấn đề liên quan