Estou recebendo erros de Tempo limite de saída R12 para um aplicativo Heroku executando unicórnio e sidekiq. Esses erros ocorrem 1 a 2 vezes por dia e sempre que eu implantar. Eu entendo que preciso converter os sinais de desligamento do Heroku para que o unicórnio responda corretamente, mas pensei que tinha feito isso na configuração do unicórnio abaixo:
worker_processes 3
timeout 30
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts "Unicorn master intercepting TERM and sending myself QUIT instead. My PID is #{Process.pid}"
Process.kill 'QUIT', Process.pid
end
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
Rails.logger.info('Disconnected from ActiveRecord')
end
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts "Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is #{Process.pid}"
end
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
Rails.logger.info('Connected to ActiveRecord')
end
Sidekiq.configure_client do |config|
config.redis = { :size => 1 }
end
end
Meus logs em torno do erro são assim:
Stopping all processes with SIGTERM
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 7
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 11
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 15
Unicorn master intercepting TERM and sending myself QUIT instead. My PID is 2
Started GET "/manage"
reaped #<Process::Status: pid 11 exit 0> worker=1
reaped #<Process::Status: pid 7 exit 0> worker=0
reaped #<Process::Status: pid 15 exit 0> worker=2
master complete
Error R12 (Exit timeout) -> At least one process failed to exit within 10 seconds of SIGTERM
Stopping remaining processes with SIGKILL
Process exited with status 137
Parece que todos os processos filho foram colhidos com êxito antes do tempo limite. É possível que o mestre ainda esteja vivo? Além disso, o roteador ainda deve estar enviando solicitações da Web ao dinamômetro durante o desligamento, conforme mostrado nos logs?
FWIW, estou usando o plug-in de implantação com tempo de inatividade zero do Heroku ( https://devcenter.heroku.com/articles/labs-preboot/ ).
Respostas:
Acho que seu tratamento de sinal personalizado é o que está causando os tempos limite aqui.
EDIT: Estou sendo reprovado por discordar da documentação do Heroku e gostaria de abordar isso.
Configurar seu aplicativo Unicorn para capturar e engolir o sinal TERM é a causa mais provável de seu aplicativo travar e não desligar corretamente.
Heroku parece argumentar que capturar e transformar um sinal TERM em um sinal QUIT é o comportamento correto para transformar um desligamento forte em um desligamento normal.
No entanto, fazer isso parece apresentar o risco de nenhum desligamento em alguns casos - a raiz desse bug. Os usuários experimentando dinos dinâmicos pendurados executando o Unicorn devem considerar a evidência e tomar suas próprias decisões com base nos primeiros princípios, não apenas na documentação.
fonte