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

Guia de uso do ferramenta de gerenciamento de processos supervisor baseado em Python

O Supervisor é uma ferramenta de gerenciamento de processos baseada em Python, que só pode ser executada no Unix-No sistema Like, ou seja, não pode ser executado no Windows. A versão oficial do Supervisor atualmente só pode ser executada no Python 2.4 nas versões acima, mas ainda não pode ser executado no Python 3 No entanto, já há um Python 3 versão portável supervisor-py3k.

Em que situações precisamos de gerenciamento de processo? É para executar programas que precisam ser executados como serviços de fundo, por exemplo, uma tarefa de fundo, a mais usada é para iniciar e gerenciar programas Web baseados em Tornado.

Além disso, o Supervisor também pode gerenciar amigavelmente os logs de saída dos programas no comando de linha, redirecionar os logs para arquivos de log personalizados e dividir os logs com base no tamanho do arquivo.

O Supervisor tem duas partes principais:

  1. supervisord, ao executar o Supervisor, ele iniciará um processo supervisord, que é responsável por iniciar os processos gerenciados e iniciá-los como seus subprocessos, e também pode reiniciar automaticamente os processos gerenciados quando eles falharem.
  2. supervisorctl, é uma ferramenta de linha de comando de gerenciamento, que pode ser usada para executar comandos como stop, start, restart, para gerenciar esses subprocessos.

Instalar

sudo pip install supervisor

Criar arquivo de configuração

echo_supervisord_conf > /etc/supervisord.conf

Se surgir um problema de falta de permissão, você pode usar este comando

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

Descrição do arquivo de configuração

Para entender como configurar o processo a ser gerenciado, basta abrir o supervisord.conf, que contém informações de comentários detalhadas.

abrir o arquivo de configuração

vim /etc/supervisord.conf

A configuração padrão do arquivo é assim, mas aqui há um buraco que precisa ser notado, supervisord.pid e supervisor.sock são colocados em /tmp diretório, mas /tmp diretório é o local de armazenamento de arquivos temporários, os arquivos dentro dele serão excluídos pelo sistema Linux, uma vez que esses arquivos se perdem, não poderão mais ser executados através do supervisorctl para executar comandos restart e stop, apenas receberão unix:///tmp/supervisor.sock não existe erro .

[unix_http_server]
;file=/tmp/supervisor.sock  ; (the path to the socket file)
;modifique para /var/diretório 'run', para evitar que seja excluído pelo sistema
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 ; (arquivo de log principal;padrão $CWD/supervisord.log)
;modifique para /var/diretório 'log', para evitar que seja excluído pelo sistema
logfile=/var/log/supervisor/supervisord.log ; (arquivo de log principal;padrão $CWD/supervisord.log)
logfile_maxbytes=50MB    ; (bytes máximos do arquivo de log principal b4 rotação;padrão 50MB)
logfile_backups=10      ; (número de cópias de backup do arquivo de log principal;padrão 10)
loglevel=info        ; (nível de log;padrão info; outros: debug,warn,trace)
;pidfile=/tmp/supervisord.pid ; (arquivo pid do supervisord;padrão supervisord.pid)
;modifique para /var/diretório 'run', para evitar que seja excluído pelo sistema
pidfile=/var/run/supervisord.pid ; (arquivo pid do supervisord;padrão supervisord.pid)
...
;configure o usuário para iniciar o supervisord, geralmente não é recomendável usar o usuário root para iniciar, a menos que você realmente tenha certeza de que deseja fazer isso
;user=chrism         ; (padrão é o usuário atual, necessário se root)
...
[supervisorctl]
; deve coincidir com a configuração de 'unix_http_server'
;serverurl=unix:///tmp/supervisor.sock; use um unix:// URL para um socket unix
;modifique para /var/diretório 'run', para evitar que seja excluído pelo sistema
serverurl=unix:///var/run/supervisor.sock; use um unix:// URL para um 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 padrão, o arquivo de log do processo atingirá5ao atingir 0MB, será dividido, mantendo no máximo10um arquivo, claro, essas configurações também podem ser configuradas individualmente para cada processo.

Problemas de permissão

Após configurar o arquivo de configuração, deve-se primeiro criar as pastas adicionadas no arquivo de configuração acima. Se foi especificado o usuário de inicialização 'user', aqui com 'oxygen' como exemplo, deve-se prestar atenção aos problemas de permissões dos arquivos relevantes, incluindo os arquivos de log, para evitar erros de falta de permissões. Por exemplo, se foi configurado o usuário de inicialização 'oxygen' e o supervisord foi iniciado, ocorreu um erro

Erro: Não é possível abrir um servidor HTTP: socket.error relatado errno.EACCES (13)

É devido ao arquivo de configuração acima /var/O diretório 'run', não foi concedido ao usuário 'oxygen' a permissão de escrita para iniciar o 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

进程的配置样例

一个简单的例子如下

; Definir o nome do processo, necessário para gerenciar o processo usando 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 ; Mover para o diretório de trabalho antes de executar o comando
user=oxygen         ; Usar o usuário oxygen para iniciar o processo
; Reiniciar automaticamente o programa em caso de falha, a quantidade de reinicializações é limitada, o padrão é3vez
autorestart=true      
redirect_stderr=true    ; Redirecionar logs de saída
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Definir nível de log

loglevel define o nível do log, as mensagens de log输出的 por meio de statements Python print não serão registradas no arquivo de log, é necessário usar o módulo logging do Python para output de logs com nível especificado.

Múltiplos processos

De acordo com a definição da documentação oficial, um [program:x] representa um grupo de processos com características ou classes idênticas, isso é, um [program:x] pode iniciar vários processos. Os membros deste grupo de processos são determinados pelos parâmetros numprocs e process_name, o que significa? Vamos ver este exemplo.

; Definir o nome do processo, necessário para gerenciar o processo usando supervisorctl
[program:foo] 
; Pode-se usar expressões python aqui no command para passar diferentes parâmetros para cada processo
command=python server.py --port=90%(process_num)02d
directory=/home/python/tornado_server ; Mover para o diretório de trabalho antes de executar o comando
; Se numprocs não for1A expressão do process_name deve conter process_num para distinguir diferentes processos
numprocs=2          
process_name=%(program_name)s_%(process_num)02d; 
user=oxygen         ; Usar o usuário oxygen para iniciar o processo
autorestart=true      ; Reiniciar automaticamente o programa em caso de falha
redirect_stderr=true    ; Redirecionar logs de saída
stdout_logfile = /var/log/supervisord/tornado_server.log
loglevel=info

Este exemplo iniciará dois processos, com process_name sendo foo:foo_01 e foo:foo_02Desta forma, é possível usar uma opção de configuração [program:x] para iniciar um grupo de processos muito semelhantes.

Vamos introduzir mais duas opções de configuração stopasgroup e killasgroup

; Padrão false, se definido como true, ao receber o sinal stop, o sinal será automaticamente enviado aos subprocessos do processo. Se esta configuração for true, implicitamente killasgroup também será true. Por exemplo, ao usar Flask em modo Debug, Flask não passa o sinal stop recebido para seus subprocessos, portanto, é necessário definir este item de configuração.

stopasgroup=false       ; enviar sinal stop ao processo UNIX 
; Padrão false, se definido como true, ao receber o sinal kill, o sinal será automaticamente enviado aos subprocessos do processo. Se este programa usar o python multiprocessing, ele pode automaticamente parar suas subthreads.
killasgroup=false       ; SIGKILL o grupo de processo UNIX (padrão false)

Exemplos de configuração mais detalhada podem ser consultados a seguir, aqui está o documento oficial

;[program:nome_do_programa]
;command=/bin/cat       ; o programa (usos relativos usam PATH, pode aceitar argumentos)
;nome_do_processo=%(nome_do_programa)s ; expressão do nome_do_processo (padrão %(nome_do_programa)s)
;numprocs=1          ; número de cópias de processos para iniciar (padrão 1)
;directory=/tmp        ; diretório para mudar para antes de executar (padrão não mudar)
;umask=022           ; máscara de permissão para o processo (padrão None)
;priority=999         ; a prioridade de início relativa (padrão 999)
;autostart=true        ; iniciar no início do supervisord (padrão: true)
;autorestart=inesperado    ; se/quando reiniciar (padrão: inesperado)
;startsecs=1          ; número de segundos que o programa deve permanecer em execução (padrão) 1)
;startretries=3        ; número máximo de falhas de início sequenciais (padrão 3)
;exitcodes=0,2         ; 'códigos de saída esperados' para o processo (padrão 0,2)
;stopsignal=QUIT        ; sinal usado para matar o processo (padrão TERM)
;stopwaitsecs=10        ; número máximo de segundos para esperar b4 SIGKILL (padrão) 10)
;stopasgroup=false       ; enviar sinal de parada para o grupo de processo UNIX (padrão false)
;killasgroup=false       ; SIGKILL o grupo de processo UNIX (padrão false)
;user=chrism          ; definir setuid para esta conta UNIX para executar o programa
;redirect_stderr=true     ; redirecionar stderr para stdout (padrão false)
;stdout_logfile=/a/caminho    ; caminho do arquivo de log stdout, NONE para nenhum; padrão AUTO
;stdout_logfile_maxbytes=1MB ; número máximo de bytes do arquivo de log b4 rotação (padrão) 50MB)
;stdout_logfile_backups=10   ; número de cópias de segurança do arquivo de log stdout (padrão 10)
;stdout_capture_maxbytes=1MB  ; número de bytes em 'capturemode' (padrão 0)
;stderr_events_enabled=false  ; emitir eventos na escrita no stdout (padrão false)
;stderr_logfile=/a/caminho    ; caminho do arquivo de log stderr, NONE para nenhum; padrão AUTO
;stderr_logfile_maxbytes=1MB ; número máximo de bytes do arquivo de log b4 rotação (padrão) 50MB)
;stderr_logfile_backups=10   ; número de cópias de segurança do arquivo de log de stderr (padrão 10)
;stderr_capture_maxbytes=1MB  ; número de bytes em 'capturemode' (padrão 0)
;stderr_events_enabled=false  ; emitir eventos em escritas no stderr (padrão false)
;environment=A="1",B="2"    ; adicionações de ambiente de processo (padrão sem adicionais)
;serverurl=AUTO        ; anular o cálculo serverurl (childutils)

Gerenciar múltiplos processos em grupos

O Supervisor também oferece outra forma de gerenciar grupos de processos, através da qual pode usar o comando supervisorctl para gerenciar um grupo de processos. Diferente do grupo de processos [program:x], aqui os processos são [program:x] individuais.

[group:thegroupname]
programs=progname1,progname2 ; cada um se refere a 'x' nas definições [program:x]
; prioridade=999         ; a prioridade de início relativa (padrão 999)

Após adicionar a configuração acima, progname1 e progname2 o nome do processo se tornará thegroupname:progname1 e thegroupname:progname2 Depois disso, deve usar esse nome para gerenciar o processo, em vez do progname anterior1.

Depois disso, execute supervisorctl stop thegroupname: para encerrar progname simultaneamente1 e progname2, execute supervisorctl stop thegroupname:progname1 Pode encerrar progname1Os comandos supervisorctl serão introduzidos mais tarde.

Iniciar supervisord

Executar o comando supervisord iniciará o processo supervisord, ao mesmo tempo, os processos configurados no arquivo de configuração também serão iniciados.

# Usa o arquivo de configuração padrão /etc/supervisord.conf
supervisord
# Especifica explicitamente o arquivo de configuração
supervisord -c /etc/supervisord.conf
# Inicia o supervisord com o usuário user
supervisord -u user

Mais parâmetros podem ser consultadosDocumento

Introdução aos comandos supervisorctl

# Para parar um processo específico, program_name é o x no [program:x]
supervisorctl stop program_name
# Inicia um processo
supervisorctl start program_name
# Reinicia um processo
supervisorctl restart program_name
# Finaliza todos os processos que pertencem ao grupo chamado groupworker (start, restart da mesma forma)
supervisorctl stop groupworker:
# Finaliza groupworker:name1 esse processo (start, restart da mesma forma)
supervisorctl stop groupworker:name1
# Para parar todos os processos, note: start, restart, stop não carregarão o arquivo de configuração mais recente
supervisorctl stop all
# Carrega o arquivo de configuração mais recente, para parar os processos existentes e inicializar e gerenciar todos os processos com novas configurações
supervisorctl reload
# Inicializa novos processos ou altera os processos com novas configurações com base no arquivo de configuração mais recente, os processos cujas configurações não foram alteradas não serão reiniciados afetados
supervisorctl update

Atenção: os processos que são parados com stop não serão reiniciados automaticamente com reload ou update. Você também pode consultaraqui

Ligar automaticamente o Supervisord ao inicializar

O Supervisord não é instalado como serviço por padrão, ele também é um processo. A equipe oficial já forneceu scripts que podem instalar o Supervisord como serviço, você pode consultar aqui para ver os scripts de instalação para diferentes sistemas operacionais, mas o script do Ubuntu fornecido oficialmente não funciona para mim.

a maneira de instalação pode ser consultada serverfault nas respostas.

por exemplo, se sou um sistema Ubuntu, posso instalar assim, aqui escolhi outro script

# 下载脚本
sudo su - root -c "sudo curl https://gist.githubusercontent.com/howthebodyworks/176149/raw/d60b505a585dda836fadecca8f6b03884153196b/supervisord.sh > /etc/init.d/supervisord"
# Configure o script para ser executável
sudo chmod +x /etc/init.d/supervisord
# Configure para executar automaticamente ao inicializar
sudo update-rc.d supervisord defaults
# Teste se ele está funcionando normalmente
service supervisord stop
service supervisord start

Atenção: Após baixar o script, verifique se ele coincide com nossa configuração, por exemplo, o caminho padrão do arquivo de configuração, o caminho do arquivo pid, etc. Se houver diferenças, algumas modificações precisam ser feitas.

Na verdade, há um método mais simples, porque o Linux executa /etc/O script dentro do rc.local, então você pode adicionar o comando de execução aqui

# Se for Ubuntu, adicione o seguinte conteúdo
/usr/local/bin/supervisord -c /etc/supervisord.conf
# Se for Centos, adicione o seguinte conteúdo
/usr/bin/supervisord -c /etc/supervisord.conf

O conteúdo acima deve ser adicionado antes do comando exit, e devido ao fato de que o variável de ambiente PATH não está completamente inicializada ao executar o script rc.local, o comando precisa usar o caminho absoluto.

Antes de adicionar, teste o comando no terminal para ver se ele pode ser executado normalmente. Se não encontrar o supervisord, você pode usar o seguinte comando para encontrá-lo

sudo find / -name supervisord

Declaração: O conteúdo deste artigo é de origem na internet, pertence ao autor original, o conteúdo é contribuído e carregado voluntariamente pelos usuários da internet, o site não possui direitos de propriedade, não foi editado manualmente e não assume responsabilidade por questões legais relacionadas. Se você encontrar conteúdo suspeito de violar direitos autorais, seja bem-vindo a enviar e-mail para: notice#oldtoolbag.com (ao enviar e-mail, substitua # por @ para denunciar, e forneça provas relevantes. Caso se confirme, o site deletará imediatamente o conteúdo suspeito de infringir direitos autorais.)

Você também pode gostar