我如何告诉独角兽了解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