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

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

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ł.


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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.