Usługi pozostają w stanie awarii po zatrzymaniu za pomocą systemctl

19

mamy prosty skrypt systemowy do uruchomienia serwera MineCraft w sposób serwisowy. SO to CentOS 7. Oto skrypt:

[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

Uruchomienie usługi działa poprawnie, ale po zatrzymaniu usługa pozostaje w stanie awarii. Widzieć:

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)

Dowolny pomysł?

Dzięki

kalise
źródło

Odpowiedzi:

27

Kod zakończenia 143 oznacza, że ​​program odebrał sygnał SIGTERM, aby nakazać mu wyjście, ale nie obsługiwał prawidłowo sygnału. Jest to prawie zawsze spowodowane błędami programistycznymi i jest dość powszechne w aplikacjach Java wszystkich typów.

Powinieneś być w stanie to ukryć, dodając kod wyjścia do pliku jednostki jako status wyjścia „sukces”:

[Service]
SuccessExitStatus=143
Michael Hampton
źródło
To działa. Teraz usługa jest nieaktywna, zgodnie z oczekiwaniami.
kalise
4
Jaki byłby „właściwy” sposób obsługi sygnału za pomocą aplikacji Java? Najbliższe, jakie mogę znaleźć, to haki zamykające, ale nigdzie w dokumentacji nie ma wzmianki, że haki zamykające zmieniają kod wyjścia aplikacji.
Spoage
@SPoage stackoverflow.com/q/2975248/1068283 Wygląda jednak na to, że Java zawsze kończy działanie z kodem 143 w tym przypadku, nawet jeśli obecny jest hak zamykania.
Michael Hampton
11

Aby uzupełnić odpowiedź Michaela, kod wyjścia 143 jest tutaj normalny, jest to sposób, w jaki maszyna wirtualna Java otrzymała sygnał SIGTERM, wysyłany przez systemd w celu zatrzymania procesu. Sygnał SIGTERM ma wartość liczbową 15 (patrz man signal).

Teraz zgodnie ze specyfikacją Posix: „Status wyjścia polecenia, które zakończyło się, ponieważ odebrał sygnał, należy zgłosić jako większy niż 128”. ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Tutaj Java VM dodaje 128 + 15 i otrzymujesz ten kod wyjścia 143.

Ten niezerowy kod wyjścia wyczuwa tutaj, ponieważ pozwala zobaczyć, że twój program Java wyszedł z powodu zewnętrznego sygnału, i masz szansę dowiedzieć się, który sygnał.

Manu
źródło
Przywoływany tekst specyfikacji POSIX wydaje się określać, jak powinna zachowywać się powłoka, i mówi: „Powłoka jest tłumaczem języka poleceń”. Java VM nie wydaje się być czymś objętym tą specyfikacją. Sposób, w jaki powłoka interpretuje maszynę wirtualną Java (lub inny program) kończącą się z powodu SIGTERM - że powinna ona ustawić kod wyjścia na 143 - z pewnością jest objęta specyfikacją, ale jestem całkiem pewien, że nie dotyczy to powłoki.
doshea
Masz rację, że ta specyfikacja POSIX jest skierowana na powłokę UNIX, ale tutaj wygląda na to, że autorzy JVM postanowili zaimplementować swój kod powrotu w ten sam sposób.
Manu,