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