
Ich habe eine systemd-Unit-Datei (serv_unit.service):
[Unit]
Description=My service
[Service]
Type=simple
Restart=always
RestartSec=60
StartLimitInterval=400
StartLimitBurst=3
ExecStart=/etc/init.d/myscript start
[Install]
WantedBy=multi-user.target
/etc/init.d/meinscript
source /etc/myfile.sh # JAVA_home & other vars are resolved through this file
mode=$1
case "$mode" in
'start')
# Start daemon
daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args &
Das Problem tritt auf, wenn ich den folgenden Befehl ausführe:
systemctl start serv_unit.service
Ich sehe keinen Java-Prozess. Aber wenn ich den Trailing-unddh:
daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
der Java-Prozess ist sichtbar (und dieser Java-Prozess stürzt nicht ab, sodass die Möglichkeit ausgeschlossen ist, dass er im Hintergrund abstürzt)
Was ist die Ursache?
Antwort1
Abgesehen von der Hauptfrage ist der Aufruf von init.d-Skripten von systemd etwas redundant und im Allgemeinen von vornherein keine gute Idee. Das ist alles, was Sie brauchen sollten:
User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
EnvironmentFile kann nur einfache KEY=value-Zuweisungen enthalten, wenn die Konfiguration jedoch in Shell-Skript-Syntax erfolgen muss, können Sie auch Folgendes verwenden:
User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"
(Sie sollten in beiden Fällen auch festlegen SyslogIdentifier=
, ob der Dienst Standardausgabemeldungen erzeugt.)
Diensttypen
Von Systemd-Diensten wird erwartet, dass sie bestimmten Regeln folgen. Eine .service
Einheit kann nur einen „Haupt“-Daemon-Prozess haben, und die Type=
Option teilt systemd mit, wie dieser Prozess funktioniert.
Type=simple
gibt an, dass der anfängliche Prozess (also der von ExecStart= gestartete) selbst der Hauptprozess des Dienstes ist. Sobald der Hauptprozess beendet wird, gilt der Dienst alsgestoppt, sodass alle Reste beseitigt werden.
Das bedeutet, dass Sie mit Type=simple systemd mitteilen, dass der Daemonwird nichtin den Hintergrund gehen. Tatsächlich sagen Sie systemd damit auch, dassdas init.d-Skript– nicht daemon
– ist der Hauptprozess des Dienstes …
Daher wäre es am besten, wenn das init.d-Skript nicht nur nicht versuchen würde, den eigentlichen Daemon in den Hintergrund zu stellen, sondern ihn auch folgendermaßen starten würde exec
:
case "$mode" in
'start-foreground')
# Start daemon in foreground
exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
Andererseits,Type=forking
zeigt an, dass der anfängliche ProzessWillefork und exit während des Startvorgangs, und dass der Hauptprozess aus PIDFile= oder heuristisch ermittelt werden sollte.
Welches soll ich verwenden?
Mit Daemons, dieeingebautDer Modus „daemonize“ Type=forking
hat einen erheblichen Vorteil: Der systemd-Dienst bleibt im Status „Starten“, bis der Daemon schließlich versucht, in den Hintergrund zu wechseln. An diesem Punkt wechselt er schließlich in den Status „Gestartet/Aktiv“. Dies hilft beim Konfigurieren von Abhängigkeiten, z. B. kann Dienst A „After=B.service“ deklarieren.
Wenn jedoch die Hintergrundverarbeitung über externe Mittel, wie z. B. die Shell-Funktion, erfolgt &
– ohne dass etwas gemeldet wird, ob der Daemon bereit ist oder nicht –, dann ist dies völlignutzlosund Sie sollten es wahrscheinlich einfach Type=simple
ohne Hintergrundoptionen verwenden.