我对罗杰的回答做了改进。通常,当底层软件出现问题导致其在短时间内大量崩溃时,您希望退避,但一旦系统恢复,您希望重置退避时间。在 Roger 的版本中,服务将始终休眠 60 秒,即使对于 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
Roger Dueck提出的解决方案最大的问题是延迟导致'restart jobName'挂起,直到sleep完成。
在确定是否休眠之前,我的添加检查是否正在进行重新启动。
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
Upstart Cookbook 建议停止后延迟 ( http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job )。使用
respawn
不带参数的节,它将永远继续尝试:(我从这个 Ask Ubuntu question得到这个)
要添加指数延迟部分,我会尝试在停止后脚本中使用环境变量,我想是这样的:
** 编辑 **
要仅在重生时应用延迟,避免真正停止时的延迟,请使用以下命令,检查当前目标是否为“停止”:
如前所述,用于
respawn
触发重生。然而,Upstart Cookbook 的报道
respawn-limit
称您需要指定respawn limit unlimited
连续重试行为。默认情况下,只要进程在 5 秒内重生不超过 10 次,它就会重试。
因此,我建议:
我最终把一个
start
放在一个cronjob中。如果该服务正在运行,则它没有任何影响。如果它没有运行,它会启动服务。我对罗杰的回答做了改进。通常,当底层软件出现问题导致其在短时间内大量崩溃时,您希望退避,但一旦系统恢复,您希望重置退避时间。在 Roger 的版本中,服务将始终休眠 60 秒,即使对于 7 次崩溃后的单个和孤立的崩溃也是如此。
您想要
respawn limit <times> <period>
- 虽然这不会提供您正在寻找的指数行为,但它可能适用于大多数用例。您可能会尝试使用非常大的值times
来period
近似您尝试实现的目标。请参阅man 5 init的部分以respawn limit
供参考。其他人已经回答了 respawn 和 respawn limit 节的问题,但我想为控制重新启动之间的延迟的停止后脚本添加我自己的解决方案。
Roger Dueck提出的解决方案最大的问题是延迟导致'restart jobName'挂起,直到sleep完成。
在确定是否休眠之前,我的添加检查是否正在进行重新启动。