あきらめるのではなく、元気を取り戻す方法


24

Upstartに2つのことをしてもらいたい:

  1. 失敗したプロセスを非常に早く再生成しようとするのをやめる
  2. 復活しようとしてあきらめない

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

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


never give up trying to respawn未回答のままです。誰でも?
vemv

回答:


29

Upstart Cookbookでは、ポストストップ遅延(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

1
引数なしでrespawnを使用する場合、デフォルトでは5分間に10回まで再試行します。
ジェイミーコックバーン

3
実稼働システムの場合の問題は、最大(60秒)に達すると、システムが正常に戻っても常に60秒かかることです。たぶんがあるかもしれません post-start、これを1にリセットするために
ホセ・F. Romaniello

2
@JamieCockburnデフォルトの間隔は5分ではなく、5 です。
-Zitrax

1
これはほとんど私にとってはうまくいきましたが、set-envトリックは「initctl:PID 1ジョブ環境を変更することはできません」をヒットしました。代わりに、私はを/ tmp / $ UPSTART_JOBでスリープ値を格納し、その後バックでそれを調達に頼る必要があった
ニール・マギル

5

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

ただし、Upstart Cookbookrespawn-limit記事には、respawn limit unlimited継続的な再試行動作を指定する必要があると書かています。

デフォルトでは、プロセスが5秒以内に10回以上再生成されない限り、再試行します。

したがって、私は提案します:

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

4

私はstartcronジョブに入れてしまった。サービスが実行されている場合、効果はありません。実行されていない場合は、サービスを開始します。


3
とてもジャンキーでエレガントです!<3
pkoch

3

ロジャーの回答を改善しました。通常、基礎となるソフトウェアに問題が発生して短時間でクラッシュする場合にバックオフしますが、システムが回復したらバックオフ時間をリセットします。Rogerのバージョンでは、サービスは常に7秒間スリープします。これは、7回のクラッシュ後の単一および個別のクラッシュでも同様です。

#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

1

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


6
期間は、リスポーン間の遅延ではなく、リスポーンがカウントされる期間です。
色あせた蜂

1
これはrespawn limit 10 3600、デフォルトで遅延がないため、10回の試行を使用してもすぐに使い果たされる可能性があることを意味すると思います。
-Zitrax

0

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

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.