2012-03-07 10 views
9

Tal vez ya has visto esta ...¿Cómo puedo decirle al unicornio que entienda las señales de Heroku?

 
2012-03-07T15:36:25+00:00 heroku[web.1]: Stopping process with SIGTERM 
2012-03-07T15:36:36+00:00 heroku[web.1]: Stopping process with SIGKILL 
2012-03-07T15:36:36+00:00 heroku[web.1]: Error R12 (Exit timeout) -> Process failed to exit within 10 seconds of SIGTERM 
2012-03-07T15:36:38+00:00 heroku[web.1]: Process exited with status 137 

Este es un problema bien conocido cuando se ejecuta en unicornheroku ...

Puede Le digo a heroku que envíe SIGQUIT? ¿O puedo decirle a unicornio que trate SIGTERM como un cierre elegante?

+0

me ascendieron no saben que yo estaba considerando unicornio para un proyecto pero esto me hace. reconsiderar. Aquí están las señales que usa thin: https://github.com/macournoyer/thin/blob/master/lib/thin/server.rb#L211 En ambos casos, QUIT señala un cierre elegante, pero INT y TERM se intercambian. –

+1

Por cierto, aquí hay otro factor: heroku enviará TERM al proceso definido en el archivo de proceso, pero luego ese proceso es responsable de entregar la señal como lo considere oportuno. Entonces, si está ejecutando su servidor detrás de bundle exec, incluso si heroku estaba enviando la señal correcta, vería el comportamiento anterior porque el servidor web no recibe la señal en absoluto. He hablado para apoyarme sobre esto y están buscando una solución. –

+2

Encontré esto hoy, no lo he explorado aún: https://github.com/ddollar/foreman/wiki/Custom-Signals –

Respuesta

6

Esto es un truco, pero he creado con éxito un archivo de configuración de unicornio que atrapa la señal TERM, impidiendo que unicornio lo reciba y realice su apagado rápido. Mi manejador de señal luego envía la señal QUIT a sí misma para activar el apagado elegante del unicornio.

Probado con Ruby 1.9.2, 4.0.1 y 4.2.1 del unicornio, Mac OS X.

listen 9292 
worker_processes 1 

# This is a hack. The code is run with 'before_fork' so it runs 
# *after* Unicorn installs its own TERM signal handler (which makes 
# this highly dependent on the Unicorn implementation details). 
# 
# We install our own signal handler for TERM and simply re-send a QUIT 
# signal to our self. 
before_fork do |_server, _worker| 
    Signal.trap 'TERM' do 
    puts 'intercepting TERM and sending myself QUIT instead' 
    Process.kill 'QUIT', Process.pid 
    end 
end 

Una preocupación es que (creo) el manejador de la señal es heredado por los procesos de trabajo. Pero el proceso de trabajo instala su propio controlador TERM, que debe sobrescribir este, por lo que no esperaría ningún problema. (Ver Unicorn::HttpServer#init_worker_process @ lib/unicorn/http_server.rb:551

Editar:.. Un detalle más, este bloque que se instala el controlador de señal se ejecutará una vez por cada proceso de trabajo (porque before_fork), pero esto simplemente redundante y no afectará nada

+2

esta es la respuesta aceptada porque a Patrick se le ocurrieron los años b4 heroku lo hizo ... pero vea la respuesta de Clay para la última respuesta autorizada –

9

Heroku proporciona ahora instrucciones para esta aquí: https://blog.heroku.com/archives/2013/2/27/unicorn_rails

Su archivo unicorn.rb sugerida es:

# config/unicorn.rb 
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' 
    Process.kill 'QUIT', Process.pid 
    end 

    defined?(ActiveRecord::Base) and 
    ActiveRecord::Base.connection.disconnect! 
end 

after_fork do |server, worker| 

    Signal.trap 'TERM' do 
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT' 
    end 

    defined?(ActiveRecord::Base) and 
    ActiveRecord::Base.establish_connection 
end 
Cuestiones relacionadas