我如何告诉独角兽了解Heroku的信号?
也许你已经看到了……
2012-03-07T15:36:25 + 00:00 heroku [web.1]:使用SIGTERM停止进程 2012-03-07T15:36:36 + 00:00 heroku [web.1]:使用SIGKILL停止进程 2012-03-07T15:36:36 + 00:00 heroku [web.1]:错误R12(退出超时) - >进程无法在SIGTERM的10秒内退出 2012-03-07T15:36:38 + 00:00 heroku [web.1]:进程退出状态为137
在heroku上运行独角兽时,这是一个众所周知的问题…
- heroku使用SIGTERM进行正常关闭
- unicorn使用SIGTERM进行快速关机
我可以告诉heroku发送SIGQUIT
吗? 或者我可以告诉独角兽将SIGTERM
视为优雅关闭吗?
这是一个黑客,但我已经成功创建了一个独特的配置文件来捕获TERM
信号,防止独角兽接收它并执行快速关机。 我的信号处理程序然后将QUIT
信号发送回自身以触发独角兽正常关闭。
使用Ruby 1.9.2,Unicorn 4.0.1和4.2.1,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
一个问题是(我相信)这个信号处理程序是由工作进程inheritance的。 但是,工作进程会安装自己的TERM
处理程序,它应该覆盖这个处理程序,因此我不希望出现任何问题。 (参见Unicorn::HttpServer#init_worker_process @ lib/unicorn/http_server.rb:551
。
编辑:还有一个细节,这个安装信号处理程序的块将每个工作进程运行一次(因为before_fork
),但这只是多余的,不会影响任何东西。
Heroku现在提供相关说明: https : //blog.heroku.com/archives/2013/2/27/unicorn_rails
他们建议的unicorn.rb文件是:
# 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