Einhorn-Exit-Timeout auf Heroku, nachdem TERM eingefangen und QUIT gesendet wurde

90

Ich erhalte R12-Exit-Timeout-Fehler für eine Heroku-App mit Einhorn und Sidekiq. Diese Fehler treten 1-2 Mal am Tag und bei jeder Bereitstellung auf. Ich verstehe, dass ich die Abschaltsignale von Heroku konvertieren muss, damit das Einhorn richtig reagiert, dachte aber, dass ich dies in der folgenden Einhornkonfiguration getan habe:

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

Meine Protokolle rund um den Fehler sehen folgendermaßen aus:

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

Es scheint, dass alle untergeordneten Prozesse vor dem Timeout erfolgreich geerntet wurden. Ist es möglich, dass der Meister noch lebt? Sollte der Router beim Herunterfahren weiterhin Webanforderungen an den Prüfstand senden, wie in den Protokollen angegeben?

FWIW, ich verwende Herokus Plugin für die Bereitstellung ohne Ausfallzeiten ( https://devcenter.heroku.com/articles/labs-preboot/ ).

middkidd
quelle
6
Wenn es hilft, tritt dieses Problem auch ohne das Plugin für die Bereitstellung ohne Ausfallzeiten auf. Ich hoffe, jemand kann helfen oder Sie können eine Antwort posten, wenn Sie es herausfinden. Wenden Sie sich vielleicht an den Heroku-Support?
Chris Peters
Genau wie Chris verwende ich keine Ausfallzeiten und habe dieses Problem. Dies trotz der von Heroku empfohlenen Einhornkonfiguration.
imderek
Ich habe das gleiche Problem, obwohl ich die von Heroku empfohlene Konfiguration verwende. Auch keine Bereitstellung ohne Ausfallzeiten.
Elsurudo
Gleiches Problem hier und ohne Preboot-Plugin.
Adrian Macneil
Eine Sache, die mir aufgefallen ist, ist, dass dies normalerweise bei Arbeiterdynos passiert. Nicht immer, aber normalerweise.
Chris Peters

Antworten:

4

Ich denke, dass Ihre benutzerdefinierte Signalverarbeitung die Zeitüberschreitungen hier verursacht.

EDIT: Ich werde herabgestimmt, weil ich mit Herokus Dokumentation nicht einverstanden bin, und ich möchte darauf eingehen.

Das Konfigurieren Ihrer Unicorn-Anwendung zum Abfangen und Verschlucken des TERM-Signals ist die wahrscheinlichste Ursache dafür, dass Ihre Anwendung hängt und nicht ordnungsgemäß heruntergefahren wird.

Heroku scheint zu argumentieren, dass das Fangen und Umwandeln eines TERM- Signals in ein QUIT Signal das richtige Verhalten ist, um ein hartes Herunterfahren in ein Herunterfahren .

Dies scheint jedoch in einigen Fällen das Risiko eines Herunterfahrens zu bergen - die Wurzel dieses Fehlers. Benutzer mit hängenden Dynos, auf denen Unicorn ausgeführt wird, sollten die Beweise berücksichtigen und ihre eigene Entscheidung auf der Grundlage erster Prinzipien und nicht nur der Dokumentation treffen.

Winfield
quelle
2
In der Heroku-Dokumentation wird immer noch " Graceful Shutdown with SIGTERM " behandelt, und ich sehe keine Erwähnung, dass dies auf dem Cedar-Stack nicht mehr erforderlich ist. Haben Sie einen Hinweis darauf, wo dies zu finden ist?
Dennis
Ich kann keine Dokumentation finden, die diese Antwort unterstützt. Laut der Dokumentation von Unicorn und Heroku verwendet Unicorn immer noch die Umkehrung der POSIX-Signalinterpretation.
Josh Kovach
Das ist nicht wahr. Unicorn wird ohne explizite Behandlung des TERM-Signals immer noch nicht ordnungsgemäß heruntergefahren. Der Dev Center Artikel, der dies unterstützt, kann hier gefunden werden: devcenter.heroku.com/articles/rails-unicorn#config
Slant
Ich erkenne, dass die Heroku-Dokumente sagen, Sie sollten versuchen, diese Signale zu fangen / zu transformieren. Die Versuche, ordnungsgemäß herunterzufahren, sind die wahrscheinlichste Ursache für Zeitüberschreitungen beim Herunterfahren.
Winfield