2011-01-10 6 views
6

Ich habe eine eingebettete Jetty 6.1.26 Instanz. Ich möchte es durch HTTP GET auf /shutdown gesendet werden. So habe ich eine JettyShutdownServlet:Anlegesteg: Programmgesteuertes Stoppen verursacht "1 Threads konnte nicht gestoppt werden"

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

Allerdings, wenn ich die Anfrage senden, wird Jetty nicht stoppen - ein Faden hält mit this.wait() in org.mortbay.thread.QueuedThreadPool auf der Linie hängen:

// 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 

Es blockiert für genau eine Minute, dann wird heruntergefahren. Ich habe den Graceful Shutdown hinzugefügt, der es mir erlauben sollte, den Server von einem Servlet herunterzufahren; Es funktioniert jedoch nicht, wie Sie aus dem Protokoll sehen können.

Ich habe es auf diese Weise gelöst:

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

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

setMaxIdleTimeMs() muss nach dem start() aufgerufen werden, becase Threadpool in start() erstellt wird. Die Threads sind jedoch bereits erstellt und warten, sodass sie erst dann angewendet werden, wenn alle Threads mindestens einmal verwendet wurden.

Ich weiß nicht, was sonst noch zu tun, außer einige schreckliche Unterbrechung aller Threads oder System.exit().

Irgendwelche Ideen? Gibt es einen guten Weg?

Danke, Ondra

+0

Ich habe gefunden, was scheint das Problem zu diskutieren - http://osdir.com/ml/java.jetty.general/2003-10/msg00074.html - aber immer noch die dankbare Abschaltung sollte diese IMO behandeln. –

Antwort

11

Graceful nicht tut, was Sie denken, es tut - sie den Server Shutdown erlaubt anmutig, aber es nicht können Sie Herunterfahren aus dem Inneren eines Servlet.

Das Problem ist wie in der Mailing-Liste Post beschrieben, mit dem Sie verlinkt - Sie versuchen, den Server zu stoppen, während Sie noch eine Verbindung im Server verarbeiten.

sollten Sie versuchen, Ihre Servlets Implementierung Wechsel zu:

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

auf diese Weise die Servlet-Verarbeitung, während der Server heruntergefahren wird beendet kann, und das Herunterfahren nicht halten.

+0

Das klingt gut, ich werde es versuchen. Vielen Dank. –

+1

Diese Lösung funktioniert. Allerdings musste ich 'Thread.sleep()' hinzufügen, um das gleiche zu verhindern - der Thread wurde zu früh ausgeführt. Also frage ich mich, wie man es blockiert, bis der Anfrage-Thread endet. 'join()' funktioniert nicht, da der Thread zurück zum Pool geht. –

+1

@Ondra Žižka Nicht sicher, ob dies immer noch relevant ist, aber pls eine Antwort auf http://stackoverflow.com/questions/5719159/programmatic-jetty-shutdown/9704012#9704012 – 01es

Verwandte Themen