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