Frage Wie man den Start zurück macht, anstatt aufzugeben


Ich möchte Emporkömmling zwei Dinge tun:

  1. Hören Sie auf, einen fehlgeschlagenen Prozess so schnell erneut zu starten
  2. gib niemals auf, Respawn zu versuchen

In einer idealen Welt würde der Emporkömmling versuchen, einen toten Prozess nach 1s neu zu starten, dann diese Verzögerung bei jedem Versuch verdoppeln, bis er eine Stunde erreicht.

Ist so etwas möglich?


25
2018-01-28 09:18


Ursprung


never give up trying to respawn bleibt unbeantwortet. jemand? - vemv


Antworten:


Das Upstart Cookbook empfiehlt eine Post-Stop-Verzögerung (http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job). Benutze die respawn Strophe ohne Argumente und es wird für immer weiter versuchen:

respawn
post-stop exec sleep 5

(Ich habe das von diese Frage Ubuntu Frage)

Um den exponentiellen Verzögerungsteil hinzuzufügen, würde ich versuchen, mit einer Umgebungsvariablen im Post-Stop-Skript zu arbeiten. Ich denke so etwas wie:

env SLEEP_TIME=1
post-stop script
    sleep $SLEEP_TIME
    NEW_SLEEP_TIME=`expr 2 \* $SLEEP_TIME`
    if [ $NEW_SLEEP_TIME -ge 60 ]; then
        NEW_SLEEP_TIME=60
    fi
    initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
end script

** BEARBEITEN **

Verwenden Sie Folgendes, um die Verzögerung nur beim erneuten Auflegen anzuwenden, indem Sie die Verzögerung bei einem echten Stopp vermeiden: Überprüfen Sie, ob das aktuelle Ziel "Stopp" ist oder nicht:

env SLEEP_TIME=1
post-stop script
    goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
    if [ $goal != "stop" ]; then
        sleep $SLEEP_TIME
        NEW_SLEEP_TIME=`expr 2 \* $SLEEP_TIME`
        if [ $NEW_SLEEP_TIME -ge 60 ]; then
            NEW_SLEEP_TIME=60
        fi
        initctl set-env SLEEP_TIME=$NEW_SLEEP_TIME
    fi
end script

31
2018-01-22 18:55



Wenn Sie Respawn ohne Argumente verwenden, wird standardmäßig bis zu zehn Mal in einem fünfminütigen Fenster versucht. - Jamie Cockburn
Das Problem damit für ein Produktionssystem ist, dass sobald Sie das Maximum (60s) erreicht haben, es immer 60 Sekunden dauern wird, selbst wenn das System wieder gesund ist. Vielleicht könnte es sein post-start um es auf 1 zurückzusetzen. - José F. Romaniello
@JamieCockburn Das Standardintervall ist nicht 5 Minuten, es ist 5 Sekunden. - Zitrax
Das hat fast für mich funktioniert - aber der set-env trick hit "initctl: Nicht erlaubt PID 1 Job-Umgebung zu modifizieren". Stattdessen musste ich den Schlafwert in / tmp / $ UPSTART_JOB speichern und dann wieder einspielen - Neil McGill


Wie bereits erwähnt, verwenden respawn um den Respawn auszulösen.

Aber die Upstart Kochbuch Berichterstattung auf respawn-limit sagt, dass Sie angeben müssen respawn limit unlimited kontinuierliches Wiederholungsverhalten haben.

Standardmäßig wird es so lange wiederholt, bis der Prozess innerhalb von 5 Sekunden nicht mehr als 10-mal respawnt.

Ich würde daher vorschlagen:

respawn
respawn limit unlimited
post-stop <script to back-off or constant delay>

5
2017-10-17 14:21





Ich landete einen start in einem Cronjob. Wenn der Dienst ausgeführt wird, hat er keine Auswirkungen. Wenn es nicht läuft, startet es den Dienst.


4
2017-10-21 08:11



So Janky und so elegant! <3 - pkoch


Ich habe Rogers Antwort verbessert. In der Regel möchten Sie einen Backoff ausführen, wenn ein Problem in der zugrunde liegenden Software auftritt, das in kurzer Zeit zu einem großen Absturz führt. Wenn das System jedoch wiederhergestellt ist, müssen Sie die Backoff-Zeit zurücksetzen. In der Version von Roger wird der Dienst immer für 60 Sekunden schlafen, auch für einzelne und isolierte Abstürze nach 7 Abstürzen.

#The initial delay.
env INITIAL_SLEEP_TIME=1

#The current delay.
env CURRENT_SLEEP_TIME=1

#The maximum delay
env MAX_SLEEP_TIME=60

#The unix timestamp of the last crash.
env LAST_CRASH=0

#The number of seconds without any crash 
#to consider the service healthy and reset the backoff.
env HEALTHY_TRESHOLD=180

post-stop script
  exec >> /var/log/auth0.log 2>&1
  echo "`date`: stopped $UPSTART_JOB"
  goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
  if [ $goal != "stop" ]; then
    CRASH_TIMESTAMP=$(date +%s)

    if [ $LAST_CRASH -ne 0 ]; then
      SECS_SINCE_LAST_CRASH=`expr $CRASH_TIMESTAMP - $LAST_CRASH`
      if [ $SECS_SINCE_LAST_CRASH -ge $HEALTHY_TRESHOLD ]; then
        echo "resetting backoff"
        CURRENT_SLEEP_TIME=$INITIAL_SLEEP_TIME
      fi
    fi

    echo "backoff for $CURRENT_SLEEP_TIME"
    sleep $CURRENT_SLEEP_TIME

    NEW_SLEEP_TIME=`expr 2 \* $CURRENT_SLEEP_TIME`
    if [ $NEW_SLEEP_TIME -ge $MAX_SLEEP_TIME ]; then
      NEW_SLEEP_TIME=$MAX_SLEEP_TIME
    fi

    initctl set-env CURRENT_SLEEP_TIME=$NEW_SLEEP_TIME
    initctl set-env LAST_CRASH=$CRASH_TIMESTAMP
  fi
end script

3
2017-10-17 19:32





Sie wollen respawn limit <times> <period> - Obwohl dies nicht das von Ihnen gewünschte exponentielle Verhalten bietet, würde es wahrscheinlich für die meisten Anwendungsfälle ausreichen. Sie könnten versuchen, sehr große Werte für zu verwenden times und period um zu approximieren, was Sie erreichen wollen. Siehe die Mann 5 InitAbschnitt auf respawn limit als Referenz.


1
2018-01-28 09:53



Der Zeitraum ist der Zeitraum, in dem Respawns sind gezähltkeine Verzögerung zwischen den Respawns. - fadedbee
Was ich annehme würde bedeuten, dass selbst wenn du benutzt hast respawn limit 10 3600 die 10 Versuche würden wahrscheinlich sofort aufgebraucht werden - da es standardmäßig keine Verzögerung gibt. - Zitrax


Andere haben die Frage nach Respawn- und Respawn-Limit-Strophen beantwortet, aber ich möchte meine eigene Lösung für das Post-Stop-Skript hinzufügen, das die Verzögerung zwischen dem Neustart steuert.

Das größte Problem mit der von Roger Dueck vorgeschlagenen Lösung besteht darin, dass die Verzögerung dazu führt, dass "restart jobName" anhält, bis der Ruhezustand abgeschlossen ist.

Mein Zusatz prüft, ob ein Neustart durchgeführt wird, bevor festgestellt wird, ob der Ruhezustand aktiviert werden soll oder nicht.

respawn
respawn limit unlimited

post-stop script
    goal=`initctl status $UPSTART_JOB | awk '{print $2}' | cut -d '/' -f 1`
    if [[ $goal != "stop" ]]; then
            if ! ps aux | grep [r]estart | grep $UPSTART_JOB; then
                    sleep 60
            fi
    fi
end script

0
2018-04-21 19:26