Dienste zuverlässig halten: systemd Restart-Strategien und Watchdog-Skripte

Egal ob Datenbankserver, Gameserver oder Streaming-Dienst — Prozesse können abstürzen, hängen oder unerwartet beendet werden. Wer nicht ständig manuell eingreifen will, braucht eine Strategie zur automatischen Wiederherstellung. Dieser Beitrag zeigt, wie man systemd und einen einfachen Watchdog kombiniert.

systemd: Restart und RestartSec

systemd bringt eingebaute Neustart-Logik mit. Für bestehende Dienste, die man nicht selbst schreibt, kann man ein Drop-in verwenden — ohne die Original-Unit zu verändern:

# /etc/systemd/system/meinservice.service.d/restart.conf
[Service]
Restart=on-failure
RestartSec=10s
StartLimitIntervalSec=60s
StartLimitBurst=3

Nach systemctl daemon-reload übernimmt systemd diese Einstellungen. Restart=on-failure startet den Dienst neu, wenn er mit einem Fehlercode endet — aber nicht bei sauberem Stopp via systemctl stop.

Restart-Modi im Überblick

  • no — kein automatischer Neustart (Standard)
  • on-failure — Neustart bei Exit-Code ≠ 0
  • on-abnormal — Neustart bei Signal/Timeout, nicht bei sauberem Exit
  • always — Neustart immer, auch nach systemctl stop — Vorsicht!
  • on-watchdog — nur bei Watchdog-Timeout (für sd_notify-fähige Dienste)

Wenn systemd nicht reicht: Shell-Watchdog

Manche Dienste zeigen Fehler, ohne zu beenden — sie hängen, antworten nicht mehr, oder der Prozess läuft, aber der Dienst ist defekt. Für diese Fälle ist ein externer Watchdog nützlich:

#!/bin/bash
# watchdog.sh — prüft ob ein Dienst aktiv ist und startet ihn ggf. neu

SERVICE="mariadb"

if ! systemctl is-active --quiet ""; then
    logger -t watchdog " nicht aktiv — starte neu"
    systemctl start ""
fi

Per Cron alle 5 Minuten ausführen:

*/5 * * * * /usr/local/bin/watchdog.sh

Erweitert: HTTP-Healthcheck

Ein Prozess kann laufen, während der Webserver hängt. Besser ist daher ein Healthcheck auf den tatsächlichen Dienst:

#!/bin/bash
# HTTP-Healthcheck für einen lokalen Webdienst

URL="http://localhost:8080/health"
MAX_FAILS=2
FAIL_FILE="/tmp/healthcheck_fails"

FAILS=0

if ! curl -sf --max-time 5 "" > /dev/null 2>&1; then
    FAILS=1
    echo "" > ""
    logger -t healthcheck "Healthcheck fehlgeschlagen (/)"

    if [ "" -ge "" ]; then
        logger -t healthcheck "Neustart ausgelöst"
        systemctl restart myservice
        echo 0 > ""
    fi
else
    echo 0 > ""
fi

Das Fail-Counter-Muster verhindert Neustarts bei kurzen Netzwerk-Ausreißern — erst nach zwei aufeinanderfolgenden Fehlern wird eingegriffen.

Logging und Alarmierung

logger schreibt in den systemd-Journal, der über journalctl -t watchdog abfragbar ist. Für aktive Benachrichtigungen kann man den Watchdog mit einer Telegram-Bot-API oder einem einfachen Mail-Aufruf kombinieren.

Kombination: das Beste aus beiden Welten

Die zuverlässigste Strategie kombiniert beide Ansätze: systemd Restart=on-failure für schnelle Neustarts bei Prozessabstürzen, plus einen externen Watchdog für hängende Prozesse und Dienste, die keine sauberen Exit-Codes zurückgeben. Zusammen decken sie die meisten Ausfallszenarien ab, ohne aufwendige Monitoring-Infrastruktur zu benötigen.