Dienste bleiben nach dem Anhalten mit systemctl im Status "Fehlgeschlagen"

19

Wir haben ein einfaches systemd-Skript, um einen MineCraft-Server auf Service-Art zu starten. Das SO ist CentOS 7. Hier das Skript:

[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

Das Starten des Dienstes funktioniert einwandfrei, aber beim Beenden bleibt der Dienst in einem fehlerhaften Zustand. Sehen:

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)

Irgendeine Idee?

Vielen Dank

kalise
quelle

Antworten:

27

Der Beendigungscode 143 bedeutet, dass das Programm ein SIGTERM-Signal zum Beenden empfangen hat, dieses jedoch nicht ordnungsgemäß verarbeitet hat. Dies liegt fast immer an Programmierfehlern und ist bei Java-Anwendungen aller Art weit verbreitet.

Sie sollten dies unterdrücken können, indem Sie den Beendigungscode als Beendigungsstatus "Erfolgreich" in die Unit-Datei einfügen:

[Service]
SuccessExitStatus=143
Michael Hampton
quelle
Es klappt. Jetzt befindet sich der Dienst erwartungsgemäß im inaktiven Status.
Kalise
4
Was wäre der "richtige" Umgang mit dem Signal in einer Java-Anwendung? Das nächste, was ich finden kann, sind Shutdown-Hooks. Nirgendwo in der Dokumentation wird erwähnt, dass Shutdown-Hooks den Exit-Code der Anwendung ändern.
SPoage
@SPoage stackoverflow.com/q/2975248/1068283 Es scheint jedoch, dass Java in diesem Fall immer mit Code 143 beendet wird, auch wenn ein Shutdown-Hook vorhanden ist.
Michael Hampton
10

Um Michaels Antwort zu ergänzen, ist der Exit-Code 143 hier normal. Auf diese Weise hat die Java-VM ein SIGTERM-Signal empfangen, das von systemd gesendet wurde, um den Prozess zu stoppen. Das SIGTERM-Signal hat einen numerischen Wert von 15 (siehe man signal).

Nun wird gemäß der Posix-Spezifikation "Der Beendigungsstatus eines Befehls, der beendet wurde, weil er ein Signal empfangen hat, als größer als 128 gemeldet". ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Hier fügt die Java VM 128 + 15 hinzu und Sie erhalten den Exit-Code 143.

Dieser Exit-Code ungleich Null ist sinnvoll, da auf diese Weise festgestellt werden kann, dass Ihr Java-Programm aufgrund eines externen Signals beendet wurde und Sie die Möglichkeit haben, herauszufinden, welches Signal vorliegt.

Manu
quelle
Der POSIX-Spezifikationstext, auf den verwiesen wird, gibt anscheinend an, wie sich eine Shell verhalten soll, und sagt: "Die Shell ist ein Befehlsspracheninterpreter." Eine Java-VM scheint von dieser Spezifikation nicht abgedeckt zu sein. Wie eine Shell eine Java-VM (oder ein anderes Programm) interpretiert, die aufgrund von SIGTERM beendet wird - dass sie den Exit-Code auf 143 setzt -, wird zwar von der Spezifikation abgedeckt, aber ich bin ziemlich sicher, dass es sich hier nicht um eine Shell handelt.
Doshea
Sie haben Recht, dass sich diese POSIX-Spezifikation an die UNIX-Shell richtet, aber hier scheinen sich die JVM-Autoren dazu entschlossen zu haben, ihren Rückkehrcode auf dieselbe Weise zu implementieren.
Manu