如何让新贵退缩,而不是放弃


24

我希望Upstart做两件事:

  1. 停止尝试如此快地重生失败的进程
  2. 永不放弃尝试重生

在理想情况下,新贵将尝试在1秒后重新启动一个死进程,然后将每次尝试的延迟加倍,直到达到一个小时。

这样的事情可能吗?


never give up trying to respawn仍然没有答案。任何人?
vemv

Answers:


29

Upstart Cookbook建议您延迟停止(http://upstart.ubuntu.com/cookbook/#delay-respawn-of-a-job)。使用respawn不带参数的节,它将永远尝试下去:

respawn
post-stop exec sleep 5

(我是从Ask 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,则默认情况下将在五分钟的窗口中最多重试十次。
Jamie Cockburn'2

3
生产系统的问题在于,一旦达到最大值(60s),即使系统恢复正常,也将始终花费60秒。也许可以将 post-start其重置为1。
JoséF. Romaniello

2
@JamieCockburn默认间隔不是5分钟,而是5
Zitrax

1
这几乎对我有用-但是set-env技巧击中了“ initctl:不允许修改PID 1作业环境”。相反,我不得不求助于将睡眠值存储在/ tmp / $ UPSTART_JOB中,然后将其重新购回
Neil McGill

5

如前所述,用于respawn触发重生。

但是,关于Upstart Cookbook的报道respawn-limit说,您需要指定respawn limit unlimited具有连续的重试行为。

默认情况下,只要该过程在5秒钟内没有重生10次以上,它就会重试。

因此,我建议:

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

4

我最终把a start放在了cronjob中。如果该服务正在运行,则无效。如果未运行,它将启动服务。


3
如此雅致又优雅!<3
pkoch 2016年

3

我对罗杰的回答做了改进。通常,当基础软件出现问题导致它在短时间内大量崩溃时,您通常想要退避,但是一旦系统恢复后,您想重置退避时间。在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

1

您想要的respawn limit <times> <period>-尽管这不能提供您要寻找的指数行为,但它可能适用于大多数用例。您可能会尝试使用非常大的值,timesperiod估算要达到的目标。有关参考,请参见man 5 init的部分respawn limit


6
周期是计算重生的时间,而不是重生之间的延迟。
褪色的蜜蜂

1
我认为这意味着即使您使用respawn limit 10 3600了10次尝试,也可能会立即用完-因为默认情况下没有延迟。
Zitrax

0

其他人已经回答了重生和重生限制节的问题,但是我想为停止后脚本添加自己的解决方案,该脚本控制重新启动之间的延迟。

Roger Dueck提出的解决方案的最大问题是延迟导致“重新启动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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.