Vermeiden Sie PID-Dateien, Crons oder alles andere, was versucht, Prozesse zu bewerten, die nicht ihre Kinder sind.
Es gibt einen sehr guten Grund, warum man in UNIX NUR auf seine Kinder warten kann. Jede Methode (ps parsing, pgrep, Speichern einer PID, ...), die versucht, dies zu umgehen, ist fehlerhaft und hat klaffende Löcher. Sagen Sie einfach no .
Stattdessen müssen Sie den Prozess, der Ihren Prozess überwacht, als Elternteil des Prozesses festlegen. Was bedeutet das? Es bedeutet, dass nur der Prozess, der startet Ihr Prozess kann zuverlässig auf sein Ende warten. In der Bash ist dies absolut trivial.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
Das obige Stück Bash-Code läuft myserver
in einem until
Schleife. Die erste Zeile beginnt myserver
und wartet darauf, dass es zu Ende geht. Wenn es endet, until
prüft seinen Exit-Status. Wenn der Exit-Status 0
bedeutet dies, dass das Programm ordnungsgemäß beendet wurde (was bedeutet, dass Sie es gebeten haben, sich irgendwie herunterzufahren, und dass es dies erfolgreich getan hat). In diesem Fall wollen wir ihn nicht neu starten (wir haben ihn ja gerade gebeten, sich zu beenden!). Wenn der Exit-Status no 0
, until
führt den Schleifenkörper aus, der eine Fehlermeldung auf STDERR ausgibt und die Schleife neu startet (zurück zu Zeile 1) nach 1 Sekunde .
Warum warten wir eine Sekunde? Weil, wenn etwas mit der Startsequenz von myserver
und es stürzt sofort ab, dann haben Sie eine sehr intensive Schleife von ständigen Neustarts und Abstürzen vor sich. Die sleep 1
nimmt dem Ganzen den Schrecken.
Jetzt brauchen Sie nur noch dieses Bash-Skript zu starten (wahrscheinlich asynchron), und es wird Folgendes überwachen myserver
und starten Sie ihn bei Bedarf neu. Wenn Sie den Monitor beim Booten starten wollen (damit der Server einen Neustart "überlebt"), können Sie ihn im cron(1) Ihres Benutzers mit einem @reboot
Regel. Öffnen Sie Ihre Cron-Regeln mit crontab
:
crontab -e
Fügen Sie dann eine Regel hinzu, um Ihr Monitor-Skript zu starten:
@reboot /usr/local/bin/myservermonitor
Alternativ können Sie auch in inittab(5) und /etc/inittab nachsehen. Sie können dort eine Zeile einfügen, in der myserver
auf einem bestimmten Init-Level starten und automatisch respawned werden.
Bearbeiten.
Lassen Sie mich einige Informationen hinzufügen, warum no um PID-Dateien zu verwenden. Sie sind zwar sehr beliebt, aber auch sehr fehlerhaft, und es gibt keinen Grund, warum man es nicht einfach auf die richtige Art und Weise machen sollte.
Bedenken Sie dies:
-
PID-Recycling (Töten des falschen Prozesses):
/etc/init.d/foo start
: Start foo
schreiben foo
PID auf /var/run/foo.pid
- Kurze Zeit später:
foo
irgendwie stirbt.
- Einige Zeit später: Jeder zufällige Prozess, der beginnt (nennen wir ihn
bar
) eine zufällige PID nimmt, stellen Sie sich vor, sie nimmt foo
die alte PID.
- Sie bemerken
foo
ist weg: /etc/init.d/foo/restart
liest /var/run/foo.pid
prüft, ob es noch lebt, und findet bar
denkt, es ist foo
tötet sie, startet eine neue foo
.
-
PID-Dateien werden veraltet. Man braucht eine überkomplizierte (oder sollte ich sagen, nicht-triviale) Logik, um zu prüfen, ob die PID-Datei veraltet ist, und jede solche Logik ist wiederum anfällig für 1.
.
-
Was ist, wenn Sie nicht einmal Schreibzugriff haben oder sich in einer Nur-Lese-Umgebung befinden?
-
Das ist eine sinnlose Überkomplizierung; sehen Sie, wie einfach mein obiges Beispiel ist. Es ist überhaupt nicht nötig, das zu komplizieren.
Siehe auch: Sind PID-Dateien immer noch fehlerhaft, wenn man es "richtig" macht?
Im Übrigen; Noch schlimmer als PID-Dateien ist das Parsen ps
! Tun Sie das niemals.
ps
ist sehr unhandlich. Man findet es zwar auf fast jedem UNIX-System, aber seine Argumente variieren stark, wenn man eine nicht standardisierte Ausgabe wünscht. Und die Standardausgabe ist NUR für den menschlichen Konsum gedacht, nicht für das Parsen durch Skripte!
- Parsing
ps
führt zu einer Fülle von Fehlalarmen. Nehmen Sie die ps aux | grep PID
Beispiel, und jetzt stellen Sie sich vor, jemand startet einen Prozess mit einer Zahl irgendwo als Argument, die zufällig die gleiche ist wie die PID, mit der Sie Ihren Daemon gestartet haben! Stellen Sie sich vor, zwei Leute starten eine X-Sitzung und Sie greifen nach X, um Ihre zu beenden. Das ist einfach alles sehr schlimm.
Wenn Sie den Prozess nicht selbst verwalten wollen, gibt es einige sehr gute Systeme, die Ihre Prozesse überwachen können. Schauen Sie sich runit zum Beispiel.