2015-04-16 13 views
22

Sto eseguendo un server Middleman (che utilizza Webrick) su JRuby all'interno di un processo JVM utilizzando l'API org.jruby.embed.ScriptingContainer.Come posso chiudere in modo pulito un JRuby incorporato in risposta a un SIGTERM per il processo JVM?

Se arresto correttamente e interrompo il server dall'interno della JVM, tutto funziona come previsto.

Ma se invio un SIGTERM al processo JVM (ad esempio, premendo ctrl + C alla riga di comando), la console ritorna ma il processo JVM non termina - si blocca indefinitamente finché non lo mando un SIGKILL .

Ho provato a registrare un hook di arresto JVM per terminare l'istanza ScriptingContainer, ma il gancio non si attiva mai. Non sono sicuro del perché ... forse JRuby sta ingoiando il SIGTERM in qualche modo?

Come è possibile arrestare la JVM fino in fondo, in modo pulito, anche se contiene un server Webrick in esecuzione?

+0

Hai verificato che il problema è JRuby, forse scambiando 'ScriptingContainer' per un'implementazione non-nulla di [' org.jruby.embed.EmbedRubyInstanceConfigAdapter'] (http://javadox.com/org.jruby/jruby -completo/1.7.13/org/jruby/embed/EmbedRubyInstanceConfigAdapter.html) e vediamo se il problema persiste? – durron597

+10

Control-C non invia SIGTERM, invia SIGINT – rghome

+2

Quale sistema operativo si utilizza? Potresti fornire un dump di thread della JVM dopo aver premuto ctrl + c? (esegui 'jstack ') Come si controlla se il gancio di arresto si attiva? –

risposta

1

Sembra che kill -9 non attivi lo shutdownHook, ma lo fa kill -15.

This StackOverflow question ha una risposta dettagliata allo stesso problema.

La linea di fondo è, sei fregato, in quanto non sembra esistere alcun modo per intercettare un segnale kill -9 ed eseguire alcune attività di manutenzione prima che la JVM si arresti.

+0

pagina man di segnali "" I segnali SIGKILL e SIGSTOP non possono essere catturati, bloccati o ignorati. "" ", Non si può veramente gestire sigkill anche nel programma C. http: // man7.org/linux/man-pages/man7/signal.7.html – workless

+0

Non ho bisogno di gestire SIGKILL ... Va bene dato che si verifica comunque un arresto completo del processo. Il mio problema è rilevare e terminare su un SIGTERM o SIGINT. – levand

+0

I segnali SIGINT e SIGTERM sono stati osservati su Linux ma in Windows non ha mai inviato questi segnali all'applicazione. – Kiran

0

In primo luogo, un trucco di debug: è possibile inviare un SIGQUIT a un processo Java per farlo stampare le tracce dello stack corrente di tutti i thread in esecuzione. Questo può aiutare a diagnosticare quali thread stanno causando l'uscita della JVM.

L'invio di un SIGINT, SIGHUP o SIGTERM fa sì che Java esegua i suoi hook di arresto, quindi esce. Puoi vedere questo in java.lang.Terminator. Una volta ricevuto il segnale, java.lang.Shutdown gestisce l'esecuzione di tutti i ganci di arresto prima di terminare il processo. Shutdown.halt() non viene chiamato fino a quando i hook di arresto non sono stati completati, il che suggerisce di avere un gancio di arresto sospeso.

Senza codice reale o tracce di stack è difficile fornire una risposta più precisa di quella, ma una JVM che rimane attiva dopo aver inviato uno SIGINT di solito fa qualcosa di strano nei suoi hook di arresto. Se ciò non è sufficiente, provare a inviare un SIGINT, attendere alcuni secondi, quindi inviare un SIGQUIT e aggiungere le tracce dello stack risultanti alla domanda.

Problemi correlati