也许你已经看过这个......
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
在unicorn上运行heroku时,这是一个众所周知的问题...
我可以告诉heroku发送SIGQUIT
吗?或者我可以告诉独角兽将SIGTERM
视为优雅关闭吗?
答案 0 :(得分:9)
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
答案 1 :(得分:6)
这是一个黑客攻击,但我已经成功创建了一个独特的配置文件来捕获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
一个问题是(我相信)这个信号处理程序是由工作进程继承的。但是,工作进程会安装自己的TERM
处理程序,它应该覆盖这个处理程序,因此我不会指望任何问题。 (见Unicorn::HttpServer#init_worker_process @ lib/unicorn/http_server.rb:551
。
编辑:还有一个细节,这个安装信号处理程序的块将在每个工作进程中运行一次(因为before_fork
),但这只是多余的,不会影响任何内容。