Hintergrund
Ich wurde gebeten, ein systemd
Skript für einen neuen Dienst zu erstellen foo_daemon
, der manchmal in einen "schlechten Zustand" gerät und nicht über "stirbt" SIGTERM
(wahrscheinlich aufgrund eines benutzerdefinierten Signal-Handlers). Dies ist für Entwickler problematisch, da sie angewiesen werden, den Dienst über Folgendes zu starten / stoppen / neu zu starten:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problem
Manchmal müssen foo_daemon
wir es aufgrund eines schlechten Zustands zwangsweise töten , indem wir:
systemctl kill -s KILL foo_daemon.service
Frage
Wie kann ich mein systemd
Skript foo_daemon
so einrichten, dass bei jedem Versuch eines Benutzers, den Dienst zu stoppen / neu zu starten, Folgendes ausgeführt systemd
wird:
- Versuchen Sie ein ordnungsgemäßes Herunterfahren von
foo_daemon
viaSIGTERM
. - Warten Sie bis zu 2 Sekunden, bis das Herunterfahren / Beenden
foo_daemon
abgeschlossen ist. - Versuchen Sie ein erzwungenes Herunterfahren von
foo_daemon
via,SIGKILL
wenn der Prozess noch aktiv ist (sodass wir nicht das Risiko haben, dass die PID recycelt wird undsystemd
ProblemeSIGKILL
mit der falschen PID auftreten). Das Gerät, auf dem wir Spawns / Forks testen, führt zu zahlreichen schnellen Prozessen. Daher besteht eine seltene, aber sehr reale Besorgnis darüber, dass das PID-Recycling ein Problem verursacht. - Wenn ich in der Praxis nur paranoid bin, was das PID-Recycling
SIGKILL
angeht , kann ich das Skript nur gegen die PID des Prozesses ausgeben , ohne mir Gedanken über das Töten einer recycelten PID zu machen.
Antworten:
systemd unterstützt dies bereits ab Werk und ist standardmäßig aktiviert .
Das einzige, was Sie anpassen möchten, ist das Timeout, mit dem Sie arbeiten können
TimeoutStopSec=
. Beispielsweise:Jetzt sendet systemd ein SIGTERM, wartet zwei Sekunden, bis der Dienst beendet ist, und wenn dies nicht der Fall ist, wird ein SIGKILL gesendet.
Wenn Ihr Dienst nicht systemabhängig ist, müssen Sie möglicherweise den Pfad zu seiner PID-Datei angeben
PIDFile=
.Schließlich haben Sie erwähnt, dass Ihr Daemon viele Prozesse erzeugt. In diesem Fall möchten Sie möglicherweise festlegen, dass
KillMode=control-group
systemd Signale an alle Prozesse in der cgroup sendet.quelle
Type=simple
in der Einheit systemd festgelegt wird.Type=forking
hat dies den Vorteil, dass (wenn der Dienst ordnungsgemäß geschrieben wurde) systemd informiert wird, wenn er vollständig "bereit" ist, was Type = simple nicht kann. Daemonisierung ist auch ohne PID-Datei kein Problem - systemd spürt den Hauptprozess trotzdem auf.Type=notify
ist am besten für systemd geeignet, und viele gängige Dienste tun dies bereits. Aber wahrscheinlich nicht dieses Vermächtnis. Im Falle des OP hat er einen Dienst, der viele Prozesse hervorbringt. Die systemd-Dokumente warnen vor diesem Fall .Da niemand die Notwendigkeit erwähnt hat,
Type=oneshot
ist hier ein vollständiges Beispiel, das aufgrund eines Timeout-Fehlers beendet wird.quelle