English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Руководство по использованию инструмента управления процессами supervisor на Python

Supervisor - это инструмент управления процессами на основе Python, который может работать только на Unix-подобных системах, то есть не может работать на Windows. Официальная версия Supervisor в настоящее время может работать только на версиях Python 2.4 и выше, но пока не может работать на Python 3, хотя уже существует移植ная версия для Python 3. supervisor-py3k

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

In addition, Supervisor can also manage the logs output by the program in a friendly way, can redirect the logs to custom log files, and can also split the logs according to file size.

Supervisor has two main components:

  1. When running Supervisor, a process called supervisord is started, which is responsible for starting the managed processes and starting them as its child processes, and can also automatically restart the managed processes if they crash.
  2. supervisorctl is a command-line management tool that can be used to execute stop, start, restart, and other commands to manage these subprocesses.

Install

sudo pip install supervisor

Create the configuration file

echo_supervisord_conf > /etc/supervisord.conf

If there is a permission issue, you can use this command

sudo su - root -c "echo_supervisord_conf > /etc/supervisord.conf"

Configuration file description

To understand how to configure the processes to be managed, just open supervisord.conf, which contains detailed comment information.

Open the configuration file

vim /etc/supervisord.conf

The default configuration file is as follows, but there is a pit to be aware of: supervisord.pid and supervisor.sock are placed in the /tmp directory, but /tmp directory is used for temporary files, and the files in it will be deleted by the Linux system. Once these files are lost, it will not be possible to execute restart and stop commands through supervisorctl anymore, and only the error 'unix:///tmp/supervisor.sock does not exist' will be received.

[unix_http_server]
;file=/tmp/supervisor.sock  ; (the path to the socket file)
; izmenite na direktoriyu /var/run, chtoby izbezhat' udaleniya sistemoyu
file=/var/run/supervisor.sock  ; (the path to the socket file)
;chmod=0700         ; socket file mode (default 0700)
;chown=nobody:nogroup    ; vладелец fayla soketa uid:gid
;username=user       ; (standartnoye yavlyaetsya bez imeni pol'zovatelya (otkrytyy server))
;password=123        ; (standartnoye yavlyaetsya bez parоля (otkrytyy server))
;[inet_http_server]     ; inet (TCP) server ne aktivirovan standartno
;port=127.0.0.1:9001    ; (ip_adres:port ukaзatel', *:port dlya vsekh interfes)
;username=user       ; (standartnoye yavlyaetsya bez imeni pol'zovatelya (otkrytyy server))
;password=123        ; (standartnoye yavlyaetsya bez parоля (otkrytyy server))
...
[supervisord]
;logfile=/tmp/supervisord.log ; (glavnyy log-fayl; standartno $CWD/supervisord.log)
; izmenite na direktoriyu /var/log, chtoby izbezhat' udaleniya sistemoyu
logfile=/var/log/supervisor/supervisord.log ; (glavnyy log-fayl; standartno $CWD/supervisord.log)
logfile_maxbytes=50MB    ; (maksimal'nyy razmer glavnogo log-fayla pri perenoske; standartno 50MB)
logfile_backups=10      ; (kol-vo rezervnyh kopiy glavnogo log-fayla; standartno 10)
loglevel=info        ; (uroven loga; standartno info; drugie: debug,warn,trace)
;pidfile=/tmp/supervisord.pid ; (pidfile supervisord; standartno supervisord.pid)
; izmenite na direktoriyu /var/run, chtoby izbezhat' udaleniya sistemoyu
pidfile=/var/run/supervisord.pid ; (pidfile supervisord; standartno supervisord.pid)
...
; nastavite polzovatelya starta supervisord, obychno ne ispol'zuyete root polzovatelya, esli ne uverены, chto eto nuzhno
;user=chrism         ; (predusmatrivaet' sovremennego polzovatelya, obychno ne ispol'zuyete root polzovatelya, esli ne uverены, chto eto nuzhno)
...
[supervisorctl]
; dolzhno soblyudat'sya sobraniem 'unix_http_server'
;serverurl=unix:///tmp/supervisor.sock ; ispolzuyete unix:// URL dlya unix soketa
; izmenite na direktoriyu /var/run, chtoby izbezhat' udaleniya sistemoyu
serverurl=unix:///var/run/supervisor.sock ; ispolzuyete unix:// URL dlya unix soketa
;serverurl=http://127.0.0.1:9001 ; ispol'zuyte http:// url dlya ukaзaniya inet soketa
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set
...

Po umolchaniyu, log fayly processov razdelyayutsya, kogda oni dostigayut 50 MB, maksimal'no sohranyayutsya 10 faylov, no eti nastroyki mogut byt' izmeneny dlya kazhdogo processa osobno.

Problemy s pravo'ami dostupa

Posle nakonchaniya nakonchaniya konfiguratsionnoy file, nado sozdaty novye papki, ukazannye v etoy konfiguratsionnoy file. Esli ukaзan pol'zovatel' dlya nachala, tak saym o oxygen, nado uverit'sya v pravo dostupa k sootvetstvuyushchim faylam, vkluchaya log fayly, v protivnom sluchae vozmozhno polozhenie bez pravo dostupa. Naprimer, esli polozhen pol'zovatel' oxygen, i nachal' process supervisord, vystupit oshibka

Oshibka: Ne mozhno otрыt' HTTP server: soobshcheny soket.error s errno.EACCES (13)

Etot polozhenie proiskhodit ot togo, chto v konfiguratsionnoy file ne predostavleny pravo pisi pol'zovatelya oxygen v papku /var/run. Pапka /var/run yavlyaetsya linkom na /run, tak zhe my izmenyaem pravo dostupa /run.

sudo chmod 777 /run

Eto polozhno prostoy i grustno, mozhet byt' polozhenie, chto izmenit' vsoj konfiguratsionnoy file .sock, .pid i druge fayly v druguyu papku i uverit'sya, chto imennoy pravo dostupa est'. V obichayushchikh usloviyakh my mozhem nachat' process supervisord s pravo'yu root i potom v processah, kotorimi on upravlyaet, ukaзat' konkretnyiy pol'zovatel', kotoriy dolzhen nachat' eti processy.

Ispol'zuyteブラウзер dlya upravleniya

Supervisor sovremennye ponyatya ponradelennoy sistema dlya upravleniya processami, dlya etogo dostatochno zakomentirovat neskol'ko strok.

;[inet_http_server]     ; inet (TCP) server ne aktivirovan standartno
;port=127.0.0.1:9001    ; (ip_adres:port ukaзatel', *:port dlya vsekh interfes)
;username=user       ; (standartnoye yavlyaetsya bez imeni pol'zovatelya (otkrytyy server))
;password=123        ; (standartnoye yavlyaetsya bez parоля (otkrytyy server))
[supervisorctl]
...
;serverurl=http://127.0.0.1:9001 ; ispol'zuyte http:// url dlya ukaзaniya inet soketa
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set

 

Use include

At the end of the configuration file, there is an [include] configuration item, like Nginx, it can include all configuration files in a folder, so we can write the configuration for each process or a few related processes separately into a file.

[include]
files = /etc/supervisord.d/*.ini

Process configuration example

Here is a simple example

; Set the process name, which is required when managing processes with supervisorctl
[program:your_program_name] 
command=python server.py --port=9000
;numprocs=1         ; The default is 1
;process_name=%(program_name)s  ; The default is %(program_name)s, that is, x in [program:x]
directory=/home/python/tornado_server ; Before executing command, switch to the working directory
user=oxygen         ; использовать пользователя oxygen для запуска процесса
; The program will restart automatically when it crashes, and the number of restarts is limited, the default is 3 times
autorestart=true      
redirect_stderr=true    ; перерidirектор outputs логов
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Set log level

loglevel specifies the log level, the logs output by Python's print statement will not be recorded in the log file, and you need to use Python's logging module to output logs with specified levels.

Multiple processes

According to the definition in the official documentation, a [program:x] actually represents a group of processes with similar features or types, that is, a [program:x] can start multiple processes. The members of this group of processes are determined by the numprocs and process_name parameters. What does this mean? Let's look at this example.

; Set the process name, which is required when managing processes with supervisorctl
[program:foo] 
; You can pass different parameters to each process using python expressions here
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; Before executing command, switch to the working directory
; Если numprocs не равно 1, выражение process_name должно содержать process_num для отличия различных процессов
numprocs=2          
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen         ; использовать пользователя oxygen для запуска процесса
autorestart=true      ; автоматически перезапускать программу при сбое
redirect_stderr=true    ; перерidirектор outputs логов
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Этот пример запустит два процесса, process_name соответственно foo:foo_01 и foo:foo_02. Таким образом, можно запустить группу очень схожих процессов с помощью параметра [program:x].

Рассмотрим еще два параметра конфигурации stopasgroup и killasgroup

; По умолчанию false, если установлено true, при получении процесса stop сигнала автоматически будет отправлен сигнал подпроцессу процесса. Если этот параметр установлен в true, это также подразумевает killasgroup true. Например, при использовании Flask в режиме отладки, Flask не передает полученный сигнал stop своим подпроцессам, поэтому необходимо установить этот параметр.

stopasgroup=false       ; отправить сигнал stop UNIX процессу 
; По умолчанию false, если установлено true, при получении процесса kill сигнала автоматически будет отправлен сигнал подпроцессу процесса. Если этот программа использует python multiprocessing, его подпотоки автоматически останавливаются.
killasgroup=false       ; SIGKILL UNIX процессной группы (по умолчанию false)

Более详细的 пример конфигурации можно найти в следующем, официальная документация здесь

;[program:theprogramname]
;command=/bin/cat       ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; выражение process_name (по умолчанию %(program_name)s)
;numprocs=1          ; количество копий процессов для запуска (по умолчанию 1)
;directory=/tmp        ; директория для cwd до выполнения (по умолчанию no cwd)
;umask=022           ; umask для процесса (по умолчанию None)
;priority=999         ; относительный приоритет запуска (по умолчанию 999)
;autostart=true        ; запуск при старте supervisord (по умолчанию: true)
;autorestart=unexpected    ; когда и как следует перезапускать (по умолчанию: unexpected)
;startsecs=1          ; количество секунд, которые программа должна оставаться запущенной (по умолчанию 1)
;startretries=3        ; максимальное количество последовательных неудач запуска (по умолчанию 3)
;exitcodes=0,2         ; 'ожидаемые' коды завершения процесса (по умолчанию 0,2)
;stopsignal=QUIT        ; сигнал, используемый для завершения процесса (по умолчанию TERM)
;stopwaitsecs=10        ; максимальное количество секунд ожидания перед SIGKILL (по умолчанию 10)
;stopasgroup=false       ; отсылка сигнала остановки процессу UNIX группы (по умолчанию false)
;killasgroup=false; SIGKILL the UNIX process group (def false)
;user=chrism; setuid to this UNIX account to run the program
;redirect_stderr=true; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false; emit events on stdout writes (default false)
;stderr_logfile=/a/path; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false; emit events on stderr writes (default false)
;environment=A="1",B="2"    ;дополнительные параметры окружения процесса (по умолчанию без добавлений)
;serverurl=AUTO        ;override serverurl computation (childutils)

Управление несколькими процессами по группам

Supervisor также предоставляет另外ой способ управления группами процессов, с помощью которого можно управлять группой процессов с помощью команды supervisorctl. В отличии от групп в [program:x], здесь процессы представляют собой отдельные [program:x].

[group:thegroupname]
programs=progname1,progname2 ; каждый из них относится к 'x' в определениях [program:x]
priority=999         ; относительная приоритетность запуска (по умолчанию 999)

После добавления вышеуказанной конфигурации имена процессов progname1 и progname2 изменятся на thegroupname:progname1 и thegroupname:progname2. В будущем для управления процессами нужно будет использовать это имя, а не прежнее progname1.

В будущем для одновременного завершения progname1 и progname2 можно использовать команду supervisorctl stop thegroupname:, для завершения только progname1 - supervisorctl stop thegroupname:progname1. Команды supervisorctl мы рассмотрим позже.

Запуск supervisord

Исполнение команды supervisord запустит процесс supervisord, а также процессы, установленные в файле конфигурации, будут соответствующим образом запущены.

# Использование mặc định файла конфигурации /etc/supervisord.conf
supervisord
# Определенно указать файл конфигурации
supervisord -c /etc/supervisord.conf
# Использование пользователя user для запуска supervisord
supervisord -u user

Более подробные параметры см.}Документация

Объяснение команды supervisorctl

# Остановить определенный процесс, program_name соответствует x в [program:x]
supervisorctl stop program_name
# Запустить определенный процесс
supervisorctl start program_name
# Перезапустить определенный процесс
supervisorctl restart program_name
# Завершить все процессы, принадлежащие к группе groupworker (start, restart аналогично)
supervisorctl stop groupworker:
# Завершить процесс groupworker:name1 (start, restart аналогично)
supervisorctl stop groupworker:name1
# Остановить все процессы, внимание: start, restart, stop не будут загружать最新的 конфигурационный файл
supervisorctl stop all
# Загрузка самого последнего конфигурационного файла, остановка текущих процессов и запуск всех процессов по новым конфигурациям
supervisorctl reload
# Запуск новых конфигураций или измененных процессов на основе最新的 конфигурационного файла, процессы, конфигурация которых не изменена, не будут перезапускаться
supervisorctl update

Внимание: процессы, остановленные с помощью stop, не будут автоматически перезапускаться при использовании reload или update. Также можно посмотретьздесь

Автоматический запуск Supervisord при загрузке системы

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

Метод установки можно посмотреть serverfault ответы.

Например, я использую систему Ubuntu, можно установить так, здесь был выбран другой скрипт

Загрузка скрипта
sudo su - root -c "sudo curl https://gist.githubusercontent.com/howthebodyworks/176149/raw/d60b505a585dda836fadecca8f6b03884153196b/supervisord.sh > /etc/init.d/supervisord"
# Установите этот скрипт как выполняемый
sudo chmod +x /etc/init.d/supervisord
# Установите автоматический запуск при загрузке системы
sudo update-rc.d supervisord defaults
# Попробуйте, работает ли это нормально
service supervisord stop
service supervisord start

Внимание: после загрузки скрипта необходимо проверить, соответствует ли он нашему конфигурации, например, путь к файлу конфигурации по умолчанию, путь к файлу pid и т.д., если они различаются, потребуется некоторые изменения.

На самом деле есть еще один простой способ, так как Linux выполняет скрипты из /etc/rc.local при запуске, поэтому вы можете добавить команду для выполнения здесь

# Если это Ubuntu, добавьте следующее содержимое
/usr/local/bin/supervisord -c /etc/supervisord.conf
# Если это Centos, добавьте следующее содержимое
/usr/bin/supervisord -c /etc/supervisord.conf

Указанное содержимое необходимо добавить перед командой exit, и поскольку переменная окружения PATH не полностью инициализирована при выполнении сценария rc.local, команда должна использовать абсолютный путь.

Прежде чем добавить, проверьте команду в терминале, чтобы убедиться, что она выполняется корректно, если supervisord не найден, вы можете использовать следующую команду для поиска

sudo find / -name supervisord

Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, содержимое предоставлено пользователями Интернета в добровольном порядке, сайт не имеет права собственности, не underwent редактирование вручную и не несет ответственности за соответствующие юридические последствия. Если вы обнаружите содержимое,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма, пожалуйста, замените # на @) для сообщения о нарушении и предоставьте соответствующие доказательства. Если после проверки будет установлено, что существует нарушение авторских прав, сайт немедленно удалят涉嫌侵权的内容。

Основной учебник
Вам может понравиться