2012-03-07 13 views
9

Forse Dopo aver visto questa ...Come posso dire all'unicorno di capire i segnali di 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 

Questo è un problema ben noto durante l'esecuzione unicorn su heroku ...

Can Dico heroku di inviare SIGQUIT? O posso dire a unicorno di trattare SIGTERM come arresto regolare?

+0

didin't sanno che mi stava prendendo in considerazione unicorno per un progetto, ma questo mi fa. riconsiderare. Ecco i segnali che utilizza sottili: https://github.com/macournoyer/thin/blob/master/lib/thin/server.rb#L211 In entrambi i casi, QUIT segnala un arresto regolare, ma INT e TERM vengono scambiati. –

+1

BTW, qui c'è un altro fattore: heroku invierà TERM al processo definito nel Procfile, ma poi quel processo è responsabile della consegna del segnale come meglio crede. Quindi, se stai eseguendo il tuo server dietro bundle exec, anche se heroku stava inviando il segnale corretto vedresti il ​​comportamento sopra perché il webserver non riceve affatto il segnale. Ho parlato di supporto per questo e stanno arrivando con una soluzione. –

+2

Ho trovato questo oggi, non ho ancora esplorato: https://github.com/ddollar/foreman/wiki/Custom-Signals –

risposta

6

Si tratta di un hack, ma ho creato con successo un file di configurazione unicorno che intrappola il segnale TERM, impedendo unicorno di ricevere e svolgere la sua spegnimento rapido. Il mio gestore di segnale invia quindi il segnale QUIT a se stesso per attivare lo spegnimento regolare dell'unicorno.

Testato con Ruby 1.9.2, 4.0.1 e 4.2.1 Unicorn, 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 preoccupazione è che (credo) questo gestore di segnale viene ereditato dai processi di lavoro. Tuttavia, il processo worker installa il proprio gestore TERM, che dovrebbe sovrascrivere questo, quindi non mi aspetto alcun problema. (Vedere Unicorn::HttpServer#init_worker_process @ lib/unicorn/http_server.rb:551

Edit:.. Un dettaglio, questo blocco che installa il gestore di segnale verrà eseguito una volta per ogni processo di lavoro (perché before_fork), ma questo solo ridondante e non pregiudica nulla

+2

questa è la risposta accettata perchè Patrick è venuto con esso anni b4 Heroku fatto ... ma vedi la risposta di Clay per l'ultima risposta autorevole –

9

Heroku offre ora istruzioni per questo qui: https://blog.heroku.com/archives/2013/2/27/unicorn_rails

loro file di unicorn.rb suggerito è:

# 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 
Problemi correlati