Как я пишу сценарий удара для перезапуска процесса, если он умирает?

Да. Если он указывает домен как .myapp.com, то myapp.com и subdomain.myapp.com могут либо прочитать, либо установить его.

212
задан Benjamin W. 20 March 2016 в 18:31
поделиться

6 ответов

Избегайте файлов PID, кронов или чего-либо еще, что пытается оценить процессы, которые не являются их детьми.

Существует очень серьезное основание, почему в UNIX, можно ТОЛЬКО ожидать на детях. Любой метод (парсинг PS, pgrep, храня PID...), который пытается работать вокруг этого, испорчен и имеет зияющие дыры в нем. Просто скажите "нет".

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

until myserver; do
    echo "Server 'myserver' crashed with exit code $?.  Respawning.." >&2
    sleep 1
done

Вышеупомянутая часть удара кодирует выполнения myserver в until цикл. Первая строка запускается myserver и ожидает его для окончания. Когда это заканчивается, until проверяет его статус выхода. Если статус выхода 0, это означает, что это закончилось корректно (что означает, что Вы попросили, чтобы это закрылось так или иначе, и это сделало так успешно). В этом случае мы не хотим перезапускать его (мы просто попросили, чтобы это закрылось!). Если статус выхода не 0, until выполнит тело цикла, которое испускает сообщение об ошибке на STDERR и перезапускает цикл (назад для выравнивания 1) после 1 секунды.

Почему мы ожидаем секунда? Поскольку, если что-то неправильно с последовательностью запуска myserver и это сразу отказывает, у Вас будет очень интенсивный цикл постоянного перезапуска и катастрофического отказа на Ваших руках. sleep 1 устраняет деформацию из этого.

Теперь все, что необходимо сделать, является запуском этот сценарий удара (асинхронно, вероятно), и он будет контролировать myserver и перезапустите его по мере необходимости. Если Вы захотите запустить монитор на начальной загрузке (заставляющий сервер "пережить" перезагрузки), то можно запланировать его в кроне пользователя (1) с @reboot правило. Откройте свои правила крона с crontab:

crontab -e

Затем добавьте правило запустить Ваш сценарий монитора:

@reboot /usr/local/bin/myservermonitor

Кроме того; взгляд inittab (5) и/etc/inittab. Можно добавить строку там, чтобы иметь myserver запустите на определенном init уровне и быть повторно порожденными автоматически.


Править.

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

Рассмотрите это:

  1. Переработка PID (уничтожающий неправильный процесс):

    • /etc/init.d/foo start: запустить foo, записать fooPID к /var/run/foo.pid
    • Некоторое время позже: foo умирает так или иначе.
    • Некоторое время позже: любой вероятностный процесс, который запускается (называют его bar) берет случайный PID, вообразите это взятием fooстарый PID.
    • Вы замечаете fooуведенный: /etc/init.d/foo/restart чтения /var/run/foo.pid, проверки, чтобы видеть, живо ли это все еще, находят bar, думает, что это foo, уничтожает его, запускает новое foo.
  2. Файлы PID идут устаревшие. Вам нужно сверхсложный (или если я говорю, нетривиальный), логика, чтобы проверить, является ли файл PID устаревшим, и любая такая логика снова уязвима для 1..

  3. Что, если Вы даже не имеете доступа для записи или находитесь в среде только для чтения?

  4. Это - бессмысленная сверхсложность; посмотрите, насколько простой мой пример выше. Никакая потребность усложнить это, вообще.

См. также: Файлы PID все еще испорчены, делая его правильно?

Между прочим; еще хуже, чем файлы PID анализирует ps! никогда не делают этого.

  1. ps является очень непортативным. В то время как Вы находите его почти в каждой системе UNIX; его аргументы варьируются значительно, если Вы хотите нестандартный вывод. И стандартный вывод ТОЛЬКО для потребления человеком, не для парсинга в виде сценария!
  2. Парсинг ps приводит к БОЛЬШОМУ КОЛИЧЕСТВУ ложных положительных сторон. Возьмите ps aux | grep PID пример, и теперь воображает кого-то начинающего процесс с числа где-нибудь как аргумент, который, оказывается, совпадает с PID, с которым Вы смотрели свой демон! Вообразите двух человек, начинающих X сессий и Вас держащий, чтобы X уничтожил Ваш. Это - просто все виды плохо.

Если Вы не хотите справляться с процессом сами; существуют некоторые совершенно хорошие системы там, которые будут действовать как монитор для Ваших процессов. Изучите runit, например.

599
ответ дан Community 23 November 2019 в 04:29
поделиться

Взгляните на monit (http://mmonit.com/monit/). Это обрабатывает, запускаются, останавливаются и перезапуск Вашего сценария и может сделать проверки состояния плюс перезапуски при необходимости.

Или сделайте простой сценарий:

while true
do
/your/script
sleep 1
done
26
ответ дан Eric 23 November 2019 в 04:29
поделиться

Самый легкий способ сделать это использует скопление на файле. В сценарии Python Вы сделали бы

lf = open('/tmp/script.lock','w')
if(fcntl.flock(lf, fcntl.LOCK_EX|fcntl.LOCK_NB) != 0): 
   sys.exit('other instance already running')
lf.write('%d\n'%os.getpid())
lf.flush()

В оболочке можно на самом деле протестировать, если она работает:

if [ `flock -xn /tmp/script.lock -c 'echo 1'` ]; then 
   echo 'it's not running'
   restart.
else
   echo -n 'it's already running with PID '
   cat /tmp/script.lock
fi

Но конечно Вы не должны тестировать, потому что, если это уже работает и Вы перезапускаете его, это выйдет с 'other instance already running'

Когда процесс умирает, все, что это - дескрипторы файлов, закрываются, и все блокировки автоматически удалены.

8
ответ дан Teddy Markov 23 November 2019 в 04:29
поделиться

Необходимо использовать monit, стандартный инструмент Unix, который может контролировать разные вещи в системе и реагировать соответственно.

Из документов: http://mmonit.com/monit/documentation/monit.html#pid_testing

check process checkqueue.py with pidfile /var/run/checkqueue.pid
       if changed pid then exec "checkqueue_restart.sh"

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

6
ответ дан clofresh 23 November 2019 в 04:29
поделиться
if ! test -f $PIDFILE || ! psgrep `cat $PIDFILE`; then
    restart_process
    # Write PIDFILE
    echo $! >$PIDFILE
fi
5
ответ дан soulmerge 23 November 2019 в 04:29
поделиться

Я с большим успехом использовал следующий сценарий на многих серверах:

pid=`jps -v | grep $INSTALLATION | awk '{print $1}'`
echo $INSTALLATION found at PID $pid 
while [ -e /proc/$pid ]; do sleep 0.1; done

примечания:

  • Он ищет Java-процесс, поэтому я можно использовать jps, это намного больше согласован во всех дистрибутивах, чем ps
  • $ INSTALLATION содержит достаточно пути к процессу, что делает его полностью однозначным
  • Используйте спящий режим, ожидая завершения процесса, избегайте перегрузки ресурсов :)

Этот сценарий фактически используется для завершения работы экземпляр tomcat, который я хочу выключить (и дождаться) в командной строке, поэтому запускать его как дочерний процесс для меня просто не вариант.

1
ответ дан 23 November 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: