Как запускать сервисы и Java приложения в фоне в Linux
Что проверяют
Отличаете ли вы «запустить, чтобы не упало при выходе из SSH» от нормальной эксплуатации сервиса: автозапуск, перезапуск при падении, логи, корректная остановка. Следом спрашивают, что происходит с JVM при systemctl stop и где смотреть логи.
Как отвечать
Покажите лестницу от ручного запуска к рабочему варианту.
&иnohup:nohup java -jar app.jar > app.log 2>&1 &. Процесс переживёт закрытие терминала, потому что игнорирует SIGHUP, но никто не поднимет его после падения или перезагрузки. Годится для разовой задачи;tmuxилиscreen: сессия живёт после отключения, к ней можно вернуться. Это инструмент для отладки и ручных прогонов, а не для прода;- systemd: основной способ на современных дистрибутивах. Юнит в
/etc/systemd/system/app.serviceсUser=,WorkingDirectory=,EnvironmentFile=,Restart=on-failureиExecStart=с полным путём кjava. Дальшеsystemctl daemon-reload,systemctl enable --now appи логи черезjournalctl -u app -f: stdout сервиса уходит в journald; - контейнер: в Docker фон и перезапуск обеспечивает
--restart unless-stoppedили оркестратор, systemd для самой JVM уже не нужен.
Два важных для Java параметра юнита. SuccessExitStatus=143: по SIGTERM JVM завершается с кодом 143, и без этой строки systemd считает штатную остановку сбоем. TimeoutStopSec= должен быть больше времени корректного завершения, иначе systemd добьёт процесс через SIGKILL. В Spring Boot корректное завершение задаёт server.shutdown=graceful. Флаг -XX:+ExitOnOutOfMemoryError заставит JVM упасть при нехватке памяти, и systemd её перезапустит, а не оставит полуживой.
Где спотыкаются
Советуют @reboot в cron как автозапуск. Нет ни перезапуска при падении, ни нормальных логов, ни управления через systemctl.
Запускают сервис из-под root. Любая уязвимость в приложении сразу даёт полный доступ к машине.
Не перенаправляют вывод при nohup: nohup.out растёт без ротации, пока не кончится место на диске.