time

supervisor: казнить нельзя, помиловать

Supervisor позволяет управлять процессами и отслеживать их состояние, в случаи непредвиденного выхода - перезапускает процесс для продолжения функционирования. Короткое сравнение с другой популярной утилитой - daemontools.

Две утилиты которые используются для организации процесса:

  • supervisord - демон, который управляет (запуск/остановка/перезапуск) процессами;
  • supervisorctl - скрипт, который общается с supervisord с помощью XML-RPC;

Установка

pip install supervisor

Supervisor поставляется с генератором конфигурационного файла, по выхлопу которого можно настроить разные детали. Ненужные на первых порах параметры закоментированы и коротко продокументированы.

echo_supervisord_conf | sudo tee /etc/supervisord.conf

Для примера был написан простой скрипт, пишущий в лог-файл I am alive - нормальная работа скрипта и Someone killed me в случаи преднамеренного убийства.

#!/usr/bin/python

import signal, time, logbook

log = logbook.Logger('APP')
handler = logbook.FileHandler('app.log')

def log_info(msg):
    with handler.applicationbound():
        log.info(msg)

def log_warn(msg):
    with handler.applicationbound():
        log.warn(msg)

def sigterm_handler(signum, frame):
    log_warn('Someone killed me.')
    exit(0)

if __name__ == "__main__":
    signal.signal(signal.SIGTERM, sigterm_handler)
    while True:
        log_info('I am alive.')
        time.sleep(1)

Теперь укажем supervisord запустить этот скрипт и перезапускать в случаи ЧП. Для этого добавим в /etc/supervisord.conf следующие строки

[program:testapp]
command=/home/proft/temp/app.py
directory=/home/proft/temp/
autorestart=true
redirect_stderr=true
stdout_logfile=/home/proft/temp/app_sd.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=50
stdout_capture_maxbytes=1MB
stdout_events_enabled=false
loglevel=warn

Запускаем supervisord

supervisord

Смотрим на статус запущенных процессов

supervisorctl status

Цепляемся к логу, генерируемого тестовым скриптом и наблюдаем за перезапуском процесса

tail -f app.log

Убиваем наш процесс

kill `pidof -x app.py`

Смотрим supervisorctl status, хотя процесс и был убит supervisord перезапустил его.

Web-интерфейс к supervisor включается через правку /etc/supervisord.conf

[inet_http_server]
port=127.0.0.1:9001

Для извещения о сбоях процессов на почту можно воспользоваться superlance.

Про запуск supervisor при загрузки ОС написано тут.

Разберемся как обновляться в случае обновления конфига.

# перезапуск всех отслеживаемых приложений, без обновления конфигов  
service supervisor restart

# перезапуск приложения <app>, без обновления конфига
supervisorctl restart <app>

# обновление конфигов всех приложений, без перезапуска 
supervisorctl reread

# перезапуск приложений для которых обновился конфиг
supervisorctl update

blog comments powered by Disqus