Как сделать выскочку обратно, а не сдаваться

Я хочу, чтобы Upstart сделал две вещи:

  1. прекратите пытаться возродить неудачный процесс так быстро
  2. никогда не сдавайся, пытаясь возродиться

В идеальном мире выскочка будет пытаться перезапустить мертвый процесс через 1 с, а затем удваивать эту задержку при каждой попытке, пока она не достигнет часа.

Возможно ли что-то подобное?

6 ответов

Upstart Cookbook рекомендует задержку после остановки ( http://upstart.ubuntu.com/cookbook/). Использовать respawn строфа без аргументов и она будет пытаться вечно

respawn
post-stop exec sleep 5

(Я получил это из этого вопроса Ask Ubuntu)

Чтобы добавить экспоненциальную задержку, я бы попробовал поработать с переменной окружения в скрипте post-stop, я думаю, что-то вроде:

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

Как уже упоминалось, используйте respawn чтобы вызвать респаун.

Тем не менее, покрытие Upstart Cookbook наrespawn-limit говорит, что вам нужно будет указать respawn limit unlimited постоянно повторять поведение.

По умолчанию он будет повторяться до тех пор, пока процесс не возродится более 10 раз за 5 секунд.

Поэтому я бы предложил:

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

Я положил start в короне Если служба работает, это не имеет никакого эффекта. Если он не запущен, он запускает службу.

Я улучшил ответ Роджера. Как правило, вы хотите выполнить откат, если в базовом программном обеспечении возникла проблема, из-за которой оно часто зависало за короткий промежуток времени, но после восстановления системы вы хотите сбросить время отката. В версии 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

Ты хочешь respawn limit <times> <period> - хотя это не обеспечит экспоненциальное поведение, которое вы ищете, оно, вероятно, подойдет для большинства случаев использования. Вы можете попробовать использовать очень большие значения для times а также period приблизиться к тому, что вы пытаетесь достичь. Смотрите раздел man 5 init на respawn limit для справки.

Другие ответили на вопрос по строкам пределов респауна и лимита респауна, но я бы хотел добавить собственное решение для скрипта post-stop, который контролирует задержку между перезапусками.

Самая большая проблема с решением, предложенным Роджером Дьюком, заключается в том, что задержка приводит к зависанию "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
Другие вопросы по тегам