Celery: Reiniciando problemas de aipo e melhor arquivo de configuração supervisionado

Criado em 9 mai. 2010  ·  16Comentários  ·  Fonte: celery/celery

Eu uso o arquivo de configuração supervisord com base no exemplo no repositório de aipo e tenho alguns problemas quando ocorre a reinicialização do celeryd: às vezes, o processamento de tarefas para silenciosamente após reiniciar o aipo sem nenhuma mensagem de erro nos logs. Os processos permanecem visíveis na lista de processos.

Finalmente, descobri que, às vezes, quando os processos são reiniciados, o aipo gera um processo adicional que não é gerenciado pelo supervisord e isso leva a esses bugs. Então comecei a observar a saída ps cuidadosamente após cada reinicialização e matar processos extras manualmente via kill. Depois de matar esses processos, as tarefas começam a ser executadas corretamente. Este é um tipo de hack que resolve um problema por uma semana ou mais.

E hoje acho que o verdadeiro motivo foi encontrado. O valor padrão do supervisord para a opção 'stopwaitsecs' é 10s. Isso significa que, após 10s, o processo de aipo será encerrado com o sinal KILL em vez de TERM. Parece que o aipo não gosta de ser morto e tenta gerar processos adicionais nesse caso.

Então, acho que será bom adicionar algo como 'stopwaitsecs=600' a todos os arquivos de configuração de exemplo do supervisor (de faq: "Você nunca deve parar o celeryd com o sinal KILL (-9), a menos que você tenha tentado TERM alguns vezes e esperei alguns minutos para deixá-lo ter a chance de desligar.") e investigue o comportamento do celeryd no sinal KILL: é mencionado nos documentos que as tarefas serão perdidas (e é tolerável em muitos casos), mas o problema com spawned processo é um pouco estranho.

Comentários muito úteis

Caso você ainda esteja tendo problemas para encerrar seus trabalhadores de aipo, você pode tentar definir stopasgroup=true antes de aumentar seu stopwaitsecs .

Todos 16 comentários

Processos gerados ao receber o sinal KILL são realmente estranhos. Eu não vejo esse comportamento quando usado fora de supervisord , então talvez isso seja causado por isso?

Se você instalar o módulo setproctitle , o aipo deve relatar o tipo de processo nas listagens de ps , você poderia fazer isso para investigar que tipo de processo é criado?

( easy_install setproctitle )

Definir o tempo limite para 600 provavelmente é bom. Existe alguma configuração para infinito (talvez com um aviso se demorar muito)? Quando celeryd é morto via TERM (que é o sinal de desligamento preferido), ele para de receber mensagens e aguarda a conclusão das tarefas atualmente em execução. E acho que para a maioria dos aplicativos, o término da execução no meio não é aceitável.

Quanto à geração do processo: setproctitle e observar os ids do processo foi útil. Não é processo de desova. Os processos de trabalho permanecem ativos quando o processo pai é eliminado.
Esta é uma simulação de reinicialização supervisionada com eliminação manual e tempo limite zero:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6101 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6108 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 nadovmeste:~# kill 6101 & kill -9 6101 &

ps -afx:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6867 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6875 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 6108 ?        S      0:00 [celeryd.PoolWorker-1]       

Consegui reproduzir isso apenas com essa corrida artificial entre kill e kill -9 . Às vezes, o trabalhador é morto corretamente. O problema parece ser específico do supervisor, porque quando inicio o celeryd no console, não tenho sorte em reproduzi-lo.

Consegui reproduzir isso com scripts iniciados pelo console após várias tentativas:

/home/nadovmeste/envs/nadovmeste/bin/python /home/nadovmeste/src/nadovmeste/manage.py celeryd -B --loglevel=INFO&

e depois em outra sessão de terminal:

nadovmeste:~# ps -afx

 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash
 9343 pts/2    Sl     0:00          \_ [celeryd.MainProcess] Running... (-B --loglevel=INFO)                                                           
 9350 pts/2    S      0:00              \_ [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00              \_ [celerybeat]     

nadovmeste:~# kill 9343 & kill -9 9343

nadovmeste:~# ps -afx

 4526 ?        Ss     0:00  \_ sshd: root@pts/1 
 4529 pts/1    Ss     0:00  |   \_ -bash
 9366 pts/1    R+     0:00  |       \_ ps -afx
 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash    
 ...
 9350 pts/2    S      0:00 [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00 [celerybeat]

Não encontrei nenhuma opção especial para tempo limite infinito com aviso nos documentos do supervisor. Provavelmente um número muito grande será suficiente se for o que queremos.

Talvez seja algo relacionado ao celerybeat porque consegui reproduzir o problema para o celeryd iniciado pelo console somente depois de usar a opção -B .

Se eu estou testando algumas tarefas de aipo localmente e eu uso a opção -B, às vezes o processo não é morto quando eu usei ctrl-c.

Não consigo reproduzir isso localmente. Aliás, você está executando o branch master? Acabei de corrigir um bug que poderia travar o desligamento. Se você pudesse testar com isso seria bom.

Sim, estou executando o branch master mais recente. Eu vi seu commit de correção de bug e esperava que isso ajudasse, mas parece que não ajuda no meu caso: o aipo mais recente parece se comportar da mesma forma. Mas é possível que o problema inicial seja resolvido - eu verifico isso apenas com um kill imediato. Não posso envolver minha mão em torno dele agora :) O problema ctrl-c não é reproduzível com minha configuração.

Então o relatório de bug, simplificado: http://gist.github.com/401028 . Os resultados são sempre os mesmos (não às vezes). Tenho algumas tarefas periódicas e outras não periódicas. As tarefas são simples e não levam muito tempo para serem concluídas. É um bug que os processos filhos permaneçam vivos depois de matar o processo principal? Se sim e você não pode reproduzi-lo, tentarei fornecer o projeto mínimo.

O comportamento de matar celerybeat é interessante: quando eu mato o processo hang(?) celerybeat, o processo de trabalho hang(?) também é encerrado.

@kmike ainda não consigo reproduzir com os comandos acima. Talvez porque eu esteja no OS X, ou talvez você esteja executando o Python 2.5? (Estou executando 2.6.1)

Poderia executá-lo com --loglevel=DEBUG? Poderia fornecer algumas informações sobre onde ele para.

O processo celerybeat é iniciado pelo processo principal, então estou assumindo que o processo principal está esperando
para o celerybeat sair antes de matar os processos restantes do pool.

Eu pensei que o processo principal foi morto: não é visível na lista de processos. Não tem muita experiência com gerenciamento de processos embora.

Minha configuração foi Debian Lenny + python 2.5.

Vou tentar executar o celeryd com --loglevel=DEBUG e reproduzi-lo no meu macbook.

hmm, você está certo, é claro. É quase como se o processo de batida se apropriasse dos processos de pool.

Eu apenas tentei reproduzir no Debian Lenny com python 2.5, e funciona bem ali.
Tentei matar com TERM e INT.

Pergunte, obrigado pela ajuda.

Eu acho que o problema inicial foi resolvido com o aumento do tempo limite do supervisor e seu commit de correção de bugs. A simulação estava incorreta porque eu uso os comandos kill -9 e eles enviam o sinal KILL em vez de TERM. Com os processos de sinal TERM estão sendo mortos corretamente.

Os supervisores usam o sinal TERM para que tudo fique bem.

Mas o que me assusta um pouco é que o bug inicial não foi investigado. Vou tentar reproduzir e te aviso.

Ah! Eu sinto muito. Não li a questão com atenção suficiente. Sim! Isso é exatamente o que acontece quando você mata com SIGKILL. O sinal 9 não pode ser capturado, então não há nada que possamos fazer sobre este AFAIK.

Caso você ainda esteja tendo problemas para encerrar seus trabalhadores de aipo, você pode tentar definir stopasgroup=true antes de aumentar seu stopwaitsecs .

Esta página foi útil?
0 / 5 - 0 avaliações