Как контролировать скорость автоматического перезапуска службы runit?

8

У меня есть этот сервис runit runи log/runскрипты работают нормально.

Когда это происходит, сама служба может зависать по внешним причинам и может не запускаться в течение многих минут. По умолчанию runit обрабатывает эту ситуацию, перезапуская службу каждые несколько секунд. Как я могу изменить это поведение?

Последним моим пониманием было добавить checkсценарий и сделать там немного магии, но это кажется намного сложнее, чем должно быть. Есть ли лучший способ проще?

jpbochi
источник

Ответы:

3

Однако я не знаком с этим средством, если бы моей задачей было решить эту проблему, а очень короткое чтение справочной страницы не предлагало простой ручки для настройки этого поведения, я бы сделал следующее:

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

Примерно так может работать (ждет не менее 1 минуты между перезапусками):

#!/bin/bash

SIGNALDIR=/tmp
SIGNALFILE=service.started

while /bin/true; do
        found=`find "${SIGNALDIR}" -maxdepth 1 -name "${SIGNALFILE}" -mmin -1 | wc -l`
        [ "${found}" -eq 0 ] && break
        echo "Waiting"
        sleep 10
done

touch "${SIGNALDIR}/${SIGNALFILE}"
original service start...
Ласло Валко
источник
Это хороший подход. Как только я протестирую его, я внесу сценарий с любыми возможными необходимыми исправлениями.
jpbochi
8

Вы должны ограничить скорость перезапусков в ./finishфайле для этой службы, которая запускается после аварийного завершения. ./finishСкрипт получит код возврата ./runи оттуда вы можете определить , что делать, и т.д. Для этого вопроса, вы должны иметь свой ./finishсценарий громко кричать о неудачах и отправке уведомлений и прыгать все вокруг в огне ...

Эйвери Пэйн
источник
Спасибо, это правильный ответ, но, к сожалению, современные программисты, использующие python, ruby ​​и т. Д., Похоже, всегда пишут приложения, которые не обращают никакого внимания на сигналы unix и не предоставляют надлежащих кодов выхода вообще.
figtrap
1
Возвращенные коды ошибок, по-видимому, "uncool", я думаю?
Эвери Пейн
похоже на это. Я считаю, что это большой шаг назад.
figtrap
1

Я на самом деле не фанат управления процессами на основе инициализации (а runit в основном является заменой инициализации). Как вы обнаруживаете, простой перезапуск неудачных процессов, как только они умирают, не является особенно хорошей стратегией. Я использовал init для перезапуска monit, но это все, что нужно. (потенциально OOM киллер мог убить Монит).

Итак, я бы посоветовал вам искать замену, а не исправлять вещи.

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

mc0e
источник
systemd, включенный в EL7 и большинство других дистрибутивов, может обрабатывать эту ситуацию и множество похожих ситуаций с огромным количеством опций и в основном делает такие менеджеры процессов устаревшими.
Майкл Хэмптон
1
Есть несколько ситуаций, когда systemd может быть «слишком большим» для целевой среды. И старый метод «управления процессами путем перезапуска до запуска» был в основном заменен надлежащим разрешением зависимостей. См. Skarnet.org/software/s6-rc и jjacky.com/anopa для примеров.
Эйвери Пэйн,