Systemd Restart = wird immer nicht beachtet

53

Hinweis: Ich habe einen Artikel über Medium geschrieben, in dem erläutert wird, wie ein Dienst erstellt und dieses spezielle Problem vermieden wird : Erstellen eines Linux-Dienstes mit systemd .

Ursprüngliche Frage:


Ich verwende systemd, um ein Arbeitsskript immer am Laufen zu halten:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

Obwohl der Neustart problemlos funktioniert, wenn das Skript nach einigen Minuten normal beendet wird, habe ich festgestellt, dass der systemdVersuch, es zu starten , einfach aufgegeben wird , wenn es beim Start wiederholt nicht ausgeführt wird:

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Wenn mein Arbeitsskript mehrmals mit dem Beendigungsstatus "" fehlschlägt 255, systemdwird der Versuch, es neu zu starten, abgebrochen:

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Gibt es eine Möglichkeit zu zwingen systemdzu immer nach ein paar Sekunden noch einmal versuchen?

Benjamin
quelle

Antworten:

53

Ich möchte Rahuls Antwort etwas erweitern.

SystemD versucht mehrmals einen Neustart ( StartLimitBurst) und bricht den Versuch ab, wenn die Anzahl der Versuche innerhalb von erreicht wird StartLimitIntervalSec. Beide Optionen gehören zum [unit]Abschnitt.

Die Standardverzögerung zwischen den Ausführungen beträgt 100 ms ( RestartSec), wodurch das Ratenlimit sehr schnell erreicht wird.

SystemD versucht nie wieder einen automatischen Neustart für Geräte mit einer definierten Neustart-Richtlinie :

Beachten Sie, dass Geräte, die für Restart=das Startlimit konfiguriert sind und dieses erreichen, nicht mehr neu gestartet werden. Sie können jedoch zu einem späteren Zeitpunkt immer noch manuell neu gestartet werden. Ab diesem Zeitpunkt wird die Neustartlogik wieder aktiviert.

Rahuls Antwort hilft, weil die längere Verzögerung verhindert, dass der Fehlerzähler innerhalb der StartLimitIntervalSecZeit erreicht wird. Die richtige Antwort ist jedoch, beide RestartSecund StartLimitBurstvernünftige Werte festzulegen.

MarSik
quelle
5
Jetzt, da ich (endlich) verstehe, wie es funktioniert, kann ich nach einigem Ausprobieren sehen, dass Ihre Antwort die richtigste ist. Fazit für mich: set StartLimitIntervalSec=0und voilà.
Benjamin
34

Ja , das gibt es. Sie können festlegen, dass der Versuch nach xSekunden wiederholt werden [Service]soll.

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

Nach dem Speichern der Datei müssen Sie die Daemon-Konfigurationen neu laden, um sicherzustellen, systemddass die neue Datei bekannt ist.

systemctl daemon-reload

Starten Sie dann den Dienst neu, um die Änderungen zu aktivieren.

systemctl restart test

Wie Sie angefordert haben, in der Dokumentation suchen,

Restart=on-failure

klingt nach einer anständigen Empfehlung.

Rahul
quelle
Es scheint in der Tat zu funktionieren, danke! Um dies besser zu verstehen, werden ohne eine RestartSecDirektive systemdmehrere Neustarts sehr schnell versucht und gehen dann in einen permanenten Fehlerzustand über. etwas, das nicht passieren kann , wenn RestartSecangegeben ist?
Benjamin
Außerdem ist mir aufgefallen, dass dies den "normalen" Neustart meines Arbeitnehmers verzögert (ich schließe den Arbeiter absichtlich nach ein paar Minuten ordnungsgemäß ab). Gibt es eine Möglichkeit, einen fehlgeschlagenen Neustart nur zu verzögern ?
Benjamin
@ Benjamin siehe meine Updates
Rahul
@ Benjamin können Sie hier für weitere Parameter überprüfen .
Rahul
3
Nach dem Doktor zu urteilen , alwaysist eine Obermenge von on-failure, also wird es nicht helfen!
Benjamin
5

systemd gibt den Versuch auf, es neu zu starten

Nein. Systemd gibt den Versuch auf, es für eine Weile neu zu starten . Dies wird in dem von Ihnen angegebenen Protokoll deutlich angezeigt:

14. Juni 11:25:51 localhost systemd [1]: test.service: Fehler mit dem Ergebnis 'start-limit' .

Dies ist eine Geschwindigkeitsbegrenzung.

Die Dauer der kurzen Wartezeit wird in der Serviceeinheit mit der StartLimitIntervalSec=Einstellung festgelegt. Die Anzahl der Starts, die innerhalb dieses Intervalls benötigt werden, um den Ratenbegrenzungsmechanismus auszulösen, wird über die StartLimitBurst=Einstellung festgelegt. Wenn sich auf Ihrem System nichts von Vanilla System D unterscheidet, einschließlich der Standardeinstellungen für diese beiden Einstellungen, ist dies innerhalb von 10 Sekunden fünfmal der Fall.

StartLimitIntervalSec=0Deaktiviert die Ratenbegrenzung, sodass systemd immer wieder versucht, anstatt aufzugeben. Es ist jedoch besser, Ihren Dienst entweder nicht so oft beenden zu lassen oder zwischen dem Beenden und dem Neustart so lange inaktiv zu lassen, bis der Grenzwert für die Übertragungsrate nicht überschritten wird.

Beachten Sie, dass es für die Geschwindigkeitsbegrenzung unerheblich ist, wie Ihr Dienst beendet wurde. Es wird unabhängig von der Ursache die Anzahl der Versuche ausgelöst, es zu starten / neu zu starten.

Weitere Lektüre

JdeBP
quelle
5
Es scheint jedoch dauerhaft aufzugeben: "Aktiv: Fehlgeschlagen (Ergebnis: Startlimit) seit Mi 2016-06-15 01:21:24 CEST; vor 12h". Es bleibt in diesem Zustand und das Skript wird nie wieder ausgeführt. Ich habe versucht, manuell StartLimitIntervalSec=10und StartLimitIntervalSec=5ohne Glück einzustellen.
Benjamin
5
Standardmäßig gibt es permanent auf. Siehe github.com/systemd/systemd/issues/2416 .
Adam Goode
2
Fazit: Um zu verhindern, dass es dauerhaft aufgibt, stellen Sie ein StartLimitIntervalSec=0.
Benjamin