Timeout di uscita dell'unicorno su Heroku dopo aver intrappolato TERM e inviato QUIT


90

Ricevo errori di timeout di uscita R12 per un'app Heroku che esegue unicorno e sidekiq. Questi errori si verificano 1-2 volte al giorno e ogni volta che eseguo la distribuzione. Capisco che devo convertire i segnali di spegnimento da Heroku affinché unicorno risponda correttamente, ma pensavo di averlo fatto nella configurazione di unicorno di seguito:

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

I miei log che circondano l'errore hanno questo aspetto:

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

Sembra che tutti i processi figlio siano stati raccolti correttamente prima del timeout. È possibile che il maestro sia ancora vivo? Inoltre, il router dovrebbe ancora inviare richieste web al banco prova durante l'arresto, come mostrato nei log?

FWIW, sto usando il plug-in di implementazione zero downtime di Heroku ( https://devcenter.heroku.com/articles/labs-preboot/ ).


6
Se aiuta, sto riscontrando questo problema anche senza il plug-in di distribuzione con tempi di inattività pari a zero. Spero che qualcuno possa aiutarti o che tu possa pubblicare una risposta se lo capisci. Forse contattare l'assistenza Heroku?
Chris Peters

Proprio come Chris, non sto utilizzando tempi di inattività pari a zero e sto riscontrando questo problema. Questo nonostante l'utilizzo della configurazione unicorno consigliata da Heroku.
imderek

Ho lo stesso problema, nonostante utilizzo la configurazione consigliata da Heroku. Nessuna implementazione con tempi di inattività pari a zero.
elsurudo

Stesso problema qui e non utilizzo del plug-in di preavvio.
Adrian Macneil

Una cosa che ho notato è che questo di solito accade sulle dinamiche dei lavoratori. Non sempre, ma di solito.
Chris Peters

Risposte:


4

Penso che la tua gestione del segnale personalizzata sia ciò che sta causando i timeout qui.

EDIT: Sto ricevendo un voto negativo per non essere d'accordo con la documentazione di Heroku e vorrei affrontare questo problema.

Configurare la tua applicazione Unicorn per catturare e inghiottire il segnale TERM è la causa più probabile della tua applicazione che si blocca e non si chiude correttamente.

Heroku sembra sostenere che catturare e trasformare un segnale TERM in un segnale QUIT sia il comportamento giusto per trasformare un arresto forzato in uno spegnimento grazioso.

Tuttavia, fare ciò sembra introdurre il rischio di non arrestarsi affatto in alcuni casi, la radice di questo bug. Gli utenti che sperimentano dinamiche sospese che eseguono Unicorn dovrebbero considerare le prove e prendere la propria decisione in base ai principi primi, non solo alla documentazione.


2
La documentazione di Heroku copre ancora " Arresto grazioso con SIGTERM ", e non vedo un accenno al fatto che non sia più necessario farlo nello stack Cedar. Hai un riferimento a dove può essere trovato?
Dennis

Non riesco a trovare alcuna documentazione che supporti questa risposta. Secondo la documentazione di Unicorn e Heroku, Unicorn utilizza ancora il contrario dell'interpretazione del segnale POSIX.
Josh Kovach

Questo non è vero. Unicorn continua a non spegnersi correttamente senza una gestione esplicita del segnale TERM. L'articolo del Dev Center che lo supporta può essere trovato qui: devcenter.heroku.com/articles/rails-unicorn#config
inclinazione

Riconosco che i documenti di Heroku dicono che dovresti provare a catturare / trasformare questi segnali. I tentativi di arresto con grazia sono la causa principale più probabile dei timeout di arresto.
Winfield
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.