it-swarm.com.de

Wie starte ich einen Linux-Hintergrundprozess automatisch neu, wenn er fehlschlägt?

Ich habe einen Prozess, der von init.d Skript im Hintergrund ausgeführt wird. Z.B:

case "$1" in 
    start)
       /bin/myprocess &
    stop)
       killall myprocess
    restart)
       killall myprocess
       /bin/myprocess &
esac

Unter bestimmten Umständen kann myprocess fehlschlagen und zurückkehren. Gibt es einen (Standard-) Weg, wie man einen Fehler erkennt und automatisch neu startet?

30
Honza

Der einfachste Weg wäre, es zu /etc/inittab hinzuzufügen, das für diese Art von Dingen entwickelt wurde:

respawn Wenn der Prozess nicht existiert, starte den Prozess. Warten Sie nicht auf die Beendigung (scannen Sie die Datei/etc/inittab weiter). Starten Sie den Prozess neu, wenn er stirbt. Wenn der Prozess vorhanden ist, tun Sie nichts und scannen Sie die Datei/etc/inittab weiter.

Zum Beispiel könnten Sie dies tun:

# Run my stuff
myprocess:2345:respawn:/bin/myprocess
14
Alan Shutko

Buildroot verfügt über drei mögliche Init-Systeme. Dazu gibt es drei Möglichkeiten:

BusyBox init

Damit fügt man einen Eintrag zu /etc/inittab hinzu.

::respawn:/bin/myprocess

Beachten Sie, dass BusyBox init ein eigenwilliges /etc/inittab-Format hat. Das zweite Feld ist bedeutungslos und das erste Feld ist keine ID , sondern ein Gerätebasisname.

Linux "System V" init

Wieder fügt man einen Eintrag zu /etc/inittab hinzu.

myprocess:2345:respawn:/bin/myprocess

systemd

Man schreibt eine Unit-Datei beispielsweise in /etc/systemd/system/myprocess.service:

[Unit]
Description=My Process

[Service]
ExecStart=/bin/myprocess
Restart=always

[Install]
WantedBy=multi-user.target

Aktivieren Sie dies, um beim Booten automatisch zu starten mit:

systemctl enable myprocess.service

Starten Sie es manuell mit:

systemctl start myprocess.service

Weitere Lektüre

25
JdeBP

Wie wäre es, eine Subshell mit einer Schleife zu erstellen, die ständig den gleichen Prozess aufruft?

Wenn es endet, wird die nächste Iteration der Schleife fortgesetzt und erneut gestartet.

(while true; do 
    /bin/myprocess
done) &

Wenn die Unterschale stirbt, ist es zwar vorbei. In diesem Fall besteht die einzige Möglichkeit darin, einen anderen Prozess zu erstellen (ich nenne ihn Nekromant), der überprüft, ob Ihr Prozess aktiv ist. Starten Sie ihn, falls dies nicht der Fall ist, und führen Sie diesen Nekromanten mit cron aus, damit Sie ihn regelmäßig überprüfen können.

Der nächste Schritt würde sich fragen, was passieren könnte, wenn cron stirbt, aber irgendwann sollten Sie sich sicher fühlen und aufhören, sich Sorgen zu machen.

22
Trylks

Sie können Monit verwenden. Es ist sehr einfach zu bedienen und sehr flexibel. In dieser Konfiguration sehen Sie beispielsweise, wie Sie den Tomcat-Prozess bei einem Fehler neu starten.

check process Tomcat with pidfile /var/run/Tomcat.pid
   start program = "/etc/init.d/Tomcat start"
   stop  program = "/etc/init.d/Tomcat stop"
   if failed port 8080 type tcp then restart

Es enthält auch viele Konfigurationsbeispiele für viele Anwendungsfälle.

3
Clyde D'Cruz

Wenn Sie kein Superuser oder Root sind und auf Ihrem Linux-System Docker installiert ist, können Sie ein Docker-Image Ihres Prozesses erstellen und den Prozess mit Docker neu starten, wenn das System neu gestartet wird.

Datei: docker-compose.yml

version: "3"
services:
  lserver:
    image: your_docker_image:latest
    ports:
    - 8080:8080   # just use 8080 as an example
    restart: always  # this is where your process can be guaranteed to restart

So starten Sie Ihren Docker-Container:

docker-compose up -d

Ich finde es einfach, meinen eigenen Prozess mit automatischem Neustart abzuwickeln, wenn ich kein Superuser des Systems bin.

Ein Beispiel für die Erstellung eines Docker-Images finden Sie hier in einem kurzen Beispiel:

Datei: Dockerfile

FROM Alpine:3.5

RUN apk update && apk upgrade && rm -rf /var/cache/apk/*
WORKDIR /app
COPY my-process-server /app
RUN ln -s /app/my-process-server /usr/local/bin/my-process-server

EXPOSE 8080

CMD ["my-process-server"]
1
Michael Qin

Sie können Anlasser verwenden

start)
   restarter -c /bin/myprocess &
stop)
   pkill -f myprocess

Verwenden Sie auf neueren Systemen systemd, um all diese trivialen Probleme zu lösen

0
sivann

In meinem Fall habe ich als schnelle Lösung die Lösung von @Trylks geändert und verwendet, um das von mir gestartete Programm zu verpacken. Ich wollte, dass es nur beim sauberen Ausgang endet.

Sollte in den meisten Shells laufen:

#!/bin/sh

echo ""
echo "Use: $0 ./program"
echo ""

#eg="/usr/bin/apt update"

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done) &
0
user1183098