Службы остаются в неисправном состоянии после остановки с помощью systemctl

19

у нас есть простой сценарий systemd для запуска сервера MineCraft сервисным способом. Так что это CentOS 7. Вот скрипт:

[Unit]
Description=Minecraft Server
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/root/Minecraft
ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
Restart=on-failure

[Install]
WantedBy=multi-user.target

Запуск службы работает нормально, но при остановке служба остается в сбойном состоянии. Видеть:

systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: active (running) since Mon 2015-06-01 16:00:12 UTC; 18s ago
 Main PID: 20975 (java)
   CGroup: /system.slice/minecraftd.service
           └─20975 /bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
systemctl stop minecraftd.service
systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: failed (Result: exit-code) since Mon 2015-06-01 16:01:37 UTC; 3s ago
  Process: 20975 ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui (code=exited, status=143)
 Main PID: 20975 (code=exited, status=143)

Любая идея?

Благодарность

kalise
источник

Ответы:

27

Код выхода 143 означает, что программа получила сигнал SIGTERM, чтобы дать ему команду выйти, но она не обработала сигнал должным образом. Это почти всегда происходит из-за ошибок программирования и довольно часто встречается в приложениях Java всех типов.

Вы должны быть в состоянии подавить это, добавив код выхода в файл модуля в качестве состояния выхода «успешно»:

[Service]
SuccessExitStatus=143
Майкл Хэмптон
источник
Оно работает. Теперь сервис находится в неактивном состоянии, как и ожидалось.
Калисе
4
Какой будет «правильный» способ обработки сигнала с помощью Java-приложения? Самым близким, что я могу найти, были бы перехватчики завершения работы, но нигде в документации не упоминается, что перехватчики отключения изменяют код выхода приложения.
SPoage
@SPoage stackoverflow.com/q/2975248/1068283 Но, похоже, в этом случае Java всегда завершает работу с кодом 143, даже если присутствует хук отключения.
Майкл Хэмптон
11

Чтобы дополнить ответ Михаэля, код выхода 143 здесь нормальный, это способ, которым java VM получает сигнал SIGTERM, отправленный systemd, чтобы остановить процесс. Сигнал SIGTERM имеет числовое значение 15 (см. man signal).

Теперь в соответствии со спецификацией Posix «Состояние завершения команды, которая завершилась, потому что она получила сигнал, должно быть сообщено как больше 128». ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Здесь Java VM добавляет 128 + 15, и вы получите этот код выхода 143.

Этот ненулевой код выхода здесь имеет смысл, так как позволяет увидеть, что ваша Java-программа вышла из-за внешнего сигнала, и вы получите возможность узнать, какой сигнал.

Manu
источник
Ссылочный текст спецификации POSIX, по-видимому, указывает, как должна вести себя оболочка, и говорит: «Оболочка является интерпретатором командного языка». Виртуальная машина Java, кажется, не покрывается этой спецификацией. То, как оболочка интерпретирует завершение Java VM (или любой другой программы) из-за SIGTERM - что она должна установить код выхода равным 143, - безусловно, охватывается спецификацией, но я вполне уверен, что здесь не используется оболочка.
доша
Вы правы в том, что эта спецификация POSIX направлена ​​на оболочку UNIX, но здесь похоже, что авторы JVM решили реализовать свой код возврата таким же образом.
Ману