Подтвердить что ты не робот

Как я могу отключить встроенный JRuby в ответ на SIGTERM для процесса JVM?

Я запускаю сервер Middleman (который использует Webrick) на JRuby внутри процесса JVM с использованием API org.jruby.embed.ScriptingContainer.

Если я завершу работу и остановил сервер изнутри JVM, все будет работать так, как ожидалось.

Но если я отправлю SIGTERM в JVM-процесс (например, нажав Ctrl + C в командной строке), консоль вернется, но процесс JVM не завершится - он висит бесконечно, пока я не отправлю его SIGKILL.

Я попробовал зарегистрировать JVM-заглушку для завершения экземпляра ScriptingContainer, но хук никогда не срабатывает. Я не знаю, почему... возможно, JRuby каким-то образом глотает SIGTERM?

Как я могу заставить JVM полностью закрыть путь, даже если он содержит запущенный сервер Webrick?

4b9b3361

Ответ 1

Похоже, что kill -9 не вызывает shutdownHook, но kill -15 делает.

fooobar.com/questions/48198/... содержит подробный ответ на ту же проблему.

Нижняя строка: вы ввернуты, поскольку, похоже, не существует способа перехватить сигнал kill -9 и выполнять некоторые задачи обслуживания до остановки JVM.

Ответ 2

Во-первых, отладочный трюк: вы можете отправить SIGQUIT в процесс Java, чтобы он смог распечатать текущие трассировки стека всех запущенных потоков. Это может помочь вам определить, какие потоки приводят к невозможности выхода JVM.

Отправка SIGINT, SIGHUP или SIGTERM приводит к тому, что Java запускает свои выключения, а затем завершает работу. Вы можете увидеть это в java.lang.Terminator. После получения сигнала java.lang.Shutdown обрабатывает все завершающие крючки перед завершением процесса. Shutdown.halt() не вызывается до тех пор, пока все завершающие крючки не закончатся, что говорит о том, что у вас есть крюк отключения, который висит.

Без реальных трассировок кода или стека трудно дать более точный ответ, но JVM, который остается живым после отправки SIGINT, обычно делает что-то странное в своих запирающих крючках. Если этого недостаточно, попробуйте отправить SIGINT, ожидая несколько секунд, затем отправив SIGQUIT и добавив результирующие трассировки стека к вопросу.