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

Guía de uso del herramienta de gestión de procesos basada en Python supervisor

Supervisor 是基于 Python 的进程管理工具,只能运行在 Unix-Like 的系统上,也就是无法运行在 Windows 上。Supervisor 官方版目前只能运行在 Python 2.4 以上版本,但是还无法运行在 Python 3 上,不过已经有一个 Python 3 versión portátil supervisor-py3k.

En qué circunstancias necesitamos la gestión de procesos? Es ejecutar programas que necesitan ejecutarse como demonios, por ejemplo, una tarea en segundo plano, el más utilizado es para lanzar y gestionar programas web basados en Tornado.

Además, Supervisor puede gestionar muy amigablemente los logs de salida de programas en la línea de comandos, puede redirigir los logs a archivos de log personalizados y puede dividir los logs según el tamaño del archivo.

Supervisor tiene dos componentes principales:

  1. supervisord, al ejecutar Supervisor, lanza un proceso supervisord, que es responsable de lanzar los procesos gestionados y lanzar estos procesos como subprocesos propios, y puede reiniciarlos automáticamente cuando los procesos gestionados se caigan.
  2. supervisorctl es una herramienta de línea de comandos para la gestión, que se puede usar para ejecutar comandos como stop, start, restart para gestionar estos subprocesos.

Instalar

sudo pip install supervisor

Crear el archivo de configuración

echo_supervisord_conf > /etc/supervisord.conf

Si surge un problema de falta de permisos, se puede usar este comando

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

Descripción del archivo de configuración

Para saber cómo configurar los procesos que se necesitan gestionar, solo hay que abrir supervisord.conf, que contiene información de comentarios detallados.

Abrir el archivo de configuración

vim /etc/supervisord.conf

La configuración predeterminada del archivo de configuración es como sigue, pero aquí hay un problema que需要注意, supervisord.pid y supervisor.sock están ubicados en /bajo el directorio tmp, pero /El directorio tmp es donde se almacenan los archivos temporales, y los archivos dentro de él serán eliminados por el sistema Linux. Una vez que estos archivos se pierdan, ya no se podrá ejecutar comandos como restart y stop mediante supervisorctl, y solo se obtendrá unix:///tmp/El error de que supervisor.sock no existe.

[unix_http_server]
;file=/tmp/supervisor.sock  ; (the path to the socket file)
; modificar a /var/directorio 'run', para evitar que el sistema lo elimine
file=/var/run/supervisor.sock  ; (the path to the socket file)
;chmod=0700         ; socket file mode (default 0700)
;chown=nobody:nogroup    ; socket file uid:gid owner
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))
;[inet_http_server]     ; inet (TCP) server disabled by default
;port=127.0.0.1:9001    ; (ip_address:port specifier, *:port for ;all iface)
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))
...
[supervisord]
;logfile=/tmp/supervisord.log ; (archivo de registro principal;por defecto $CWD/supervisord.log)
; modificar a /var/directorio 'log', para evitar que el sistema lo elimine
logfile=/var/log/supervisor/supervisord.log ; (archivo de registro principal;por defecto $CWD/supervisord.log)
logfile_maxbytes=50MB    ; (bytes máximos del archivo de registro principal b4 rotación;por defecto 50MB)
logfile_backups=10      ; (número de copias de respaldo del archivo de registro principal;por defecto 10)
loglevel=info        ; (nivel de registro;por defecto info; otros: debug,warn,trace)
;pidfile=/tmp/supervisord.pid ; (archivo pid de supervisord;por defecto supervisord.pid)
; modificar a /var/directorio 'run', para evitar que el sistema lo elimine
pidfile=/var/run/supervisord.pid ; (archivo pid de supervisord;por defecto supervisord.pid)
...
;establecer el usuario que inicia supervisord, generalmente no se debe usar el usuario root para iniciar, a menos que realmente esté seguro de hacerlo
;user=chrism         ; (por defecto es el usuario actual, requerido si es root)
...
[supervisorctl]
; debe coincidir con la configuración de 'unix_http_server'
;serverurl=unix:///tmp/supervisor.sock; usar un unix:// URL para un socket unix
; modificar a /var/directorio 'run', para evitar que el sistema lo elimine
serverurl=unix:///var/run/supervisor.sock; usar un unix:// URL para un socket unix
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set
...

Por defecto, cuando el archivo de registro del proceso alcanza5Al alcanzar 0MB, se realizará una división, manteniendo como máximo10archivos, por supuesto, estas configuraciones también pueden ser configuradas por separado para cada proceso.

Problemas de permisos

Después de configurar el archivo de configuración, debe crear primero las carpetas adicionales especificadas en el archivo de configuración. Si se especificó el usuario de inicio 'user', por ejemplo 'oxygen', debe prestar atención a los problemas de permisos de los archivos relevantes, incluyendo los archivos de registro, de lo contrario se producirá un error sin permisos. Por ejemplo, si se configuró el usuario de inicio 'oxygen' y luego se inició supervisord, se produjo un error

Error: No se puede abrir un servidor HTTP: se informó socket.error errno.EACCES (13)

Es debido a que en el archivo de configuración anterior /var/El archivo 'run' no tiene permisos de escritura otorgados al usuario 'oxygen' para iniciar supervisord./var/run 文件夹实际上是链接到 /run,因此我们修改 /run 的权限。

sudo chmod 777 /run

这样有点简单粗暴,也可以考虑把上述配置文件中 .sock,.pid 等文件修改到其他文件夹中,并确保有相应的权限即可。一般情况下,我们可以用 root 用户启动 supervisord 进程,然后在其所管理的进程中,再具体指定需要以那个用户启动这些进程。

使用浏览器来管理

supervisor 同时提供了通过浏览器来管理进程的方法,只需要注释掉如下几行就可以了。

;[inet_http_server]     ; inet (TCP) server disabled by default
;port=127.0.0.1:9001    ; (ip_address:port specifier, *:port for ;all iface)
;username=user       ; (default is no username (open server))
;password=123        ; (default is no password (open server))
[supervisorctl]
...
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris       ; should be same as http_username if set
;password=123        ; should be same as http_password if set

 

使用 include

在配置文件的最后,有一个 [include] 的配置项,跟 Nginx 一样,可以 include 某个文件夹下的所有配置文件,这样我们就可以为每个进程或相关的几个进程的配置单独写成一个文件。

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

进程的配置样例

一个简单的例子如下

; Establecer el nombre del proceso, es necesario usar este nombre de proceso al gestionar procesos con supervisorctl
[program:your_program_name] 
command=python server.py --port=9000
;numprocs=1         ; 默认为1
;process_name=%(program_name)s  ; 默认为 %(program_name)s,即 [program:x] 中的 x
directory=/home/python/tornado_server ; Cambiar al directorio de trabajo antes de ejecutar el command
user=oxygen         ; Usar el usuario oxygen para iniciar este proceso
; Reiniciar automáticamente el programa cuando se cuelgue, el número de reinicios es limitado, por defecto de}}3vez
autorestart=true      
redirect_stderr=true    ; Redirigir los registros de salida
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Configurar el nivel de registro

loglevel especifica el nivel de registro, los registros de salida impresos con la declaración print de Python no se registrarán en el archivo de registro, se necesita combinar con el módulo logging de Python para registrar registros con un nivel especificado.

Múltiples procesos

De acuerdo con la definición de la documentación oficial, un [program:x] representa realmente un grupo de procesos con características o clases similares, es decir, un [program:x] puede iniciar varios procesos. Los miembros de este grupo de procesos se determinan mediante los parámetros numprocs y process_name, ¿qué significa esto? Vamos a ver este ejemplo.

; Establecer el nombre del proceso, es necesario usar este nombre de proceso al gestionar procesos con supervisorctl
[program:foo] 
; Se pueden pasar diferentes parámetros a cada proceso utilizando expresiones python aquí en el command
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; Cambiar al directorio de trabajo antes de ejecutar el command
; Si numprocs no es1El expresión de process_name debe contener process_num para distinguir diferentes procesos
numprocs=2          
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen         ; Usar el usuario oxygen para iniciar este proceso
autorestart=true      ; Reiniciar automáticamente el programa cuando se cuelgue
redirect_stderr=true    ; Redirigir los registros de salida
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Este ejemplo iniciará dos procesos, con process_name分别为 foo:foo_01 y foo:foo_02De esta manera, se puede usar un elemento de configuración [program:x] para iniciar un grupo de procesos muy similares.

Vamos a presentar dos opciones de configuración stopasgroup y killasgroup

; Por defecto es false, si se establece en true, al recibir la señal stop del proceso, se enviará automáticamente la señal a los subprocesos del proceso. Si esta opción está configurada en true, también implica que killasgroup está configurado en true. Por ejemplo, al usar Flask en modo Debug, Flask no transmitirá la señal stop recibida a sus subprocesos, por lo que es necesario configurar esta opción.

stopasgroup=false       ; enviar señal stop al proceso UNIX 
; Por defecto es false, si se establece en true, al recibir la señal kill del proceso, se enviará automáticamente la señal a los subprocesos del proceso. Si este programa utiliza multiprocessing de python, se puede detener automáticamente sus subprocesos.
killasgroup=false       ; enviar SIGKILL al grupo de procesos UNIX (por defecto false)

Ejemplos de configuración más detallados, pueden referirse a lo siguiente, la documentación oficial aquí

;[program:theprogramname]
;command=/bin/cat       ; el programa (usar PATH para rutas relativas, puede tomar argumentos)
;process_name=%(program_name)s ; expresión del nombre del proceso (por defecto %(program_name)s)
;numprocs=1          ; número de copias de procesos para comenzar (por defecto 1)
;directory=/tmp        ; directorio al que cambiar antes de ejecutar (por defecto no cambiar directorio)
;umask=022           ; máscara umask para el proceso (por defecto None)
;prioridad=999         ; la prioridad de inicio relativa (por defecto 999)
;autostart=true        ; comenzar en el inicio de supervisord (por defecto: true)
;autorestart=inesperado    ; si/cuándo reiniciar (por defecto: inesperado)
;startsecs=1          ; número de segundos que el programa debe seguir ejecutándose (por defecto) 1)
;startretries=3        ; max # of serial start failures (default 3)
;exitcodes=0,2         ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT        ; signal used to kill process (default TERM)
;stopwaitsecs=10        ; max num secs to wait b4 SIGKILL (predeterminado 10)
;stopasgroup=false       ; send stop signal to the UNIX process group (default false)
;killasgroup=false       ; SIGKILL the UNIX process group (predeterminado false)
;user=chrism          ; setuid to this UNIX account to run the program
;redirect_stderr=true     ; redirect proc stderr to stdout (predeterminado false)
;stdout_logfile=/a/path    ; stdout log path, NONE for none; predeterminado AUTO
;stdout_logfile_maxbytes=1MB  ; max # logfile bytes b4 rotation (predeterminado 50MB)
;stdout_logfile_backups=10   ; # of stdout logfile backups (predeterminado 10)
;stdout_capture_maxbytes=1MB  ; número de bytes en 'capturemode' (por defecto 0)
;stdout_events_enabled=false  ; emit events on stdout writes (predeterminado false)
;stderr_logfile=/a/path    ; stderr log path, NONE for none; predeterminado AUTO
;stderr_logfile_maxbytes=1MB  ; max # logfile bytes b4 rotation (predeterminado 50MB)
;stderr_logfile_backups=10   ; número de respaldos de archivos de registro de stderr (por defecto 10)
;stderr_capture_maxbytes=1MB  ; número de bytes en 'capturemode' (por defecto 0)
;stderr_events_enabled=false  ; emitir eventos en escrituras de stderr (por defecto false)
;environment=A="1",B="2"    ; agregar entorno de proceso (def no adds)
;serverurl=AUTO        ; anular el cálculo de serverurl (childutils)

Gestionar múltiples procesos en grupos

Supervisor también ofrece otro método de gestión de grupos de procesos, a través de este método, se puede gestionar un grupo de procesos utilizando el comando supervisorctl. A diferencia del grupo de procesos [program:x], aquí los procesos son [program:x] individuales.

[group:thegroupname]
programs=progname1,progname2 ; cada uno se refiere a 'x' en las definiciones [program:x]
; prioridad=999         ; la prioridad de inicio relativa (por defecto 999)

Después de agregar la configuración anterior, progname1 y progname2 El nombre del proceso se convertirá en thegroupname:progname1 y thegroupname:progname2 En el futuro, se utilizará este nombre para gestionar los procesos, en lugar de progname1.

En el futuro, ejecutar supervisorctl stop thegroupname: también finalizará progname1 y progname2, ejecutar supervisorctl stop thegroupname:progname1 Podrá finalizar progname1Supervisorctl nos lo explicaremos más adelante.

Iniciar supervisord

Ejecutar el comando supervisord iniciará el proceso supervisord, al mismo tiempo, también se iniciarán los procesos configurados en el archivo de configuración.

# 使用默认的配置文件 /etc/supervisord.conf
supervisord
# 明确指定配置文件
supervisord -c /etc/supervisord.conf
# 使用 user 用户启动 supervisord
supervisord -u user

更多参数请参考文档

supervisorctl 命令介绍

# 停止某一个进程,program_name 为 [program:x] 里的 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"
# Establecer este script para que sea ejecutable
sudo chmod +x /etc/init.d/supervisord
# Establecer para ejecutar automáticamente al iniciar el sistema
sudo update-rc.d supervisord defaults
# Pruebe si funciona correctamente
service supervisord stop
service supervisord start

Atención: después de descargar este script,还应检查它与我们的配置是否相符,例如默认的 configuración de archivo de ruta, ruta de archivo pid, etc. Si hay diferencias, se deben realizar algunas modificaciones.

En realidad, hay un método más simple, porque Linux ejecuta /etc/El script dentro de rc.local, por lo que solo debe agregar aquí la ejecución del comando

# Si es Ubuntu, agregue el siguiente contenido
/usr/local/bin/supervisord -c /etc/supervisord.conf
# Si es Centos, agregue el siguiente contenido
/usr/bin/supervisord -c /etc/supervisord.conf

Este contenido debe agregarse antes del comando exit, y debido a que el variable de entorno PATH no se inicializa completamente al ejecutar el script rc.local, el comando debe usar la ruta absoluta.

Antes de agregar, pruebe el comando en la terminal para ver si se puede ejecutar correctamente. Si no puede encontrar supervisord, puede usar el siguiente comando para encontrarlo

sudo find / -name supervisord

Declaración: El contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha realizado un procesamiento editorial manual y no asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará