web-dev-qa-db-ja.com

あきらめるのではなく、新興企業を元に戻す方法

Upstartで2つのことを実行してください。

  1. 失敗したプロセスを非常に速くリスポーンしようとするのをやめる
  2. リスポーンしようとあきらめることはありません

理想的な世界では、upstartは1秒後にデッドプロセスの再起動を試み、1時間に達するまで、試行ごとにその遅延を2倍にします。

このようなことは可能ですか?

24
fadedbee

Upstartクックブックは、停止後の遅延を推奨しています( http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job )。 respawnスタンザを引数なしで使用すると、永久に試行を続けます。

respawn
post-stop exec sleep 5

(私はこれを これはUbuntuに質問します )から取得しました

指数遅延部分を追加するには、ポストストップスクリプトで環境変数を操作してみます。

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

**編集**

リスポーン時にのみ遅延を適用し、実際のストップでの遅延を回避するには、次のコマンドを使用して、現在の目標が「ストップ」であるかどうかを確認します。

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
29
Roger Dueck

すでに述べたように、respawnを使用してリスポーンをトリガーします。

ただし、 respawn-limit に関するUp-start Cookbookのカバレッジでは、継続的に再試行するためにはrespawn limit unlimitedを指定する必要があると述べています。

デフォルトでは、プロセスが5秒間に10回を超えて再起動しない限り、再試行します。

したがって、私はお勧めします:

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

私はstartをcronjobに入れました。サービスが実行中の場合、影響はありません。実行されていない場合は、サービスを開始します。

4
fadedbee

ロジャーの答えを改善しました。通常、基盤となるソフトウェアに問題があり、短時間で大量のクラッシュが発生する場合にバックオフしますが、システムが回復したら、バックオフ時間をリセットします。ロジャーのバージョンでは、サービスは、7回のクラッシュ後の単一の孤立したクラッシュでも、常に60秒間スリープします。

#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

respawn limit <times> <period>が欲しい-これはあなたが探している指数的な振る舞いを提供しないであろうが、それはおそらくほとんどのユースケースでそうなるだろう。 timesperiodに非常に大きな値を使用して、達成しようとしていることを概算することができます。参考として、respawn limitの-​​ man 5 init のセクションを参照してください。

1
the-wabbit

他の人がrespawnおよびrespawn limitスタンザに関する質問に回答していますが、再起動間の遅延を制御するポストストップスクリプト用の独自のソリューションを追加したいと思います。

Roger Dueckによって提案されたソリューションの最大の問題は、スリープが完了するまで、遅延により「restart jobName」がハングすることです。

さらに、スリープするかどうかを決定する前に、再起動が進行中かどうかを確認します。

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
Whitham Reeve