Processo de encerramento de upstart e de sinal múltiplo

1

Estou executando um serviço de trabalho de resque no Ubuntu e quero gerenciá-lo usando o upstart (o gerenciador de processos padrão do Ubuntu).

Uma sequência de desligamento adequada para um trabalhador de resque é enviar primeiro o sinal QUIT e aguardar que o processo conclua qualquer trabalho em execução primeiro. Deve então se parar. Se o trabalhador não desligar em tempo hábil - porque o trabalho ainda está em execução (possivelmente travado), preciso enviar um sinal TERM , que fará com que o processo de trabalho aborte o trabalho e saia. E, obviamente, se isso não funcionar, um sinal KILL teria que ser enviado.

A maneira que pensei em implementar isso é ter um pre-start script para enviar o sinal QUIT e depois dormir até que o processo exista ou o tempo limite expire.

Mas, na prática, o que acontece é que, se o trabalhador responder a QUIT e sair, respawn entra em ação e reinicia o processo que aparentemente faz com que o processo de parada não aconteça.

Existe uma maneira de começar a não renascer se estamos parando o processo de qualquer maneira?

    
por Guss 18.10.2015 / 19:11

2 respostas

2

Existem duas maneiras que encontrei para resolver o problema, e nem é perfeito:

  1. Upstart tem a sub-rotina kill signal . Se você definir kill signal QUIT e também kill timeout 600 , o Upstart enviará SIGQUIT para o processo e aguarde 600 segundos antes de enviar SIGKILL . Se o processo terminar antes de SIGKILL ser enviado, então estamos bem. Há problemas com essa abordagem: (a) ele envia SIGKILL e não SIGTERM após o tempo limite que não permite que o trabalhador de resque se feche bem, mas isso não é nada demais. (b) Um problema pior que eu descobri é que o upstart envia o "kill signal" (no nosso caso SIGQUIT ) para todos os processos da sessão, o que provavelmente interferirá na operação de processos filhos do resque worker (% co_de A ação% padrão é terminar com um dump principal).
  2. Implemente seu próprio wrapper que aprisiona qualquer sinal que seu upstart configurado envie (ou apenas assuma o padrão SIGQUIT ) e lide com todo o desligamento normal. Nesse caso, é importante configurar o Upstart SIGTERM para um tempo suficiente para permitir que o wrapper execute um encerramento normal e force a interrupção com o tempo esgotado (nesse caso, certifique-se de ter o tempo limite um pouco menor que o Upstart) ou apenas confie no kill timeout do Upstart para a limpeza (o que pode ou não ser uma boa ideia dependendo dos seus requisitos). Contras: é bastante complicado fazer isso direito, e a razão pela qual o Upstart existe é que você não precisará escrever um gerenciador de processo para cada serviço.

Se você não quer ir de qualquer forma, existem outros gerenciadores de processos que podem implementar um sistema de sinal mais complexo que o Upstart, e estes geralmente são fáceis de implementar sob o Upstart para gerenciar apenas o processo que você está tendo. um problema com. Infelizmente, é difícil encontrar um que funcione corretamente em todos os casos. Por exemplo, eu tentei Bluepill , que parece ótimo no papel, mas no momento da escrita tem um bug gritante onde se você tente um regime de sinal complexo com múltiplos sinais e múltiplos timeouts, ele apenas envia todos os sinais de uma vez (não necessariamente na ordem correta) e trava o processo filho.

Se alguém tiver mais informações para adicionar, sinta-se à vontade para adicionar mais respostas e eu posso até marcá-las como "respondidas" (em vez da minha resposta), se estiver bom.

    
por 05.11.2015 / 11:50
0

De Upstart livro de receitas :

Since the job's goal will already be 'stop' when a pre-stop is run, you can shutdown the process through any means, and the process won't be re-spawned (even with the respawn stanza).

Você pode tentar enviar QUIT na seção pre-stop do seu script.

    
por 24.02.2016 / 00:32

Tags