捕获TERM并发送QUIT后,Heroku上的独角兽退出超时


90

我收到一个运行独角兽和sidekiq的Heroku应用程序的R12退出超时错误。每当我部署时,这些错误每天都会发生1-2次。我知道我需要转换Heroku的关闭信号以使独角兽正确响应,但我认为我已经在以下独角兽配置中这样做了:

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. My PID is #{Process.pid}"
    Process.kill 'QUIT', Process.pid
  end

  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
    Rails.logger.info('Disconnected from ActiveRecord')
  end
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts "Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is #{Process.pid}"
  end

  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
    Rails.logger.info('Connected to ActiveRecord')
  end

  Sidekiq.configure_client do |config|
    config.redis = { :size => 1 }
  end
end

我的错误日志如下所示:

Stopping all processes with SIGTERM
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 7
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 11
Unicorn worker intercepting TERM and doing nothing. Wait for master to sent QUIT. My PID is 15
Unicorn master intercepting TERM and sending myself QUIT instead. My PID is 2
Started GET "/manage"
reaped #<Process::Status: pid 11 exit 0> worker=1
reaped #<Process::Status: pid 7 exit 0> worker=0
reaped #<Process::Status: pid 15 exit 0> worker=2
master complete
Error R12 (Exit timeout) -> At least one process failed to exit within 10 seconds of SIGTERM
Stopping remaining processes with SIGKILL
Process exited with status 137

看来,所有子进程在超时之前都已成功获得。主人可能还活着吗?另外,如日志所示,路由器在关闭期间是否仍应向dyno发送Web请求?

FWIW,我正在使用Heroku的零停机部署插件(https://devcenter.heroku.com/articles/labs-preboot/)。


6
如果有帮助,我也遇到了这个问题,而不零停机时间部署插件。我希望有人可以帮助您,如果您能找到答案,可以发布答案。也许联系Heroku支持?
克里斯·彼得斯

就像克里斯一样,我没有使用零停机时间,而是遇到了这个问题。尽管使用了Heroku建议的独角兽配置。
imderek

尽管使用了Heroku推荐的配置,但我遇到了同样的问题。也没有零停机时间部署。
elsurudo

同样的问题在这里,并且不使用预启动插件。
Adrian Macneil

我注意到的一件事是,这种情况通常发生在工人测功机上。并非总是如此,但通常如此。
克里斯·彼得斯

Answers:


4

我认为您的自定义信号处理是造成此处超时的原因。

编辑:我因不同意Heroku的文档而感到沮丧,我想解决这个问题。

配置Unicorn应用程序以捕获并吞下TERM信号是最可能导致应用程序挂起且无法正确关闭的原因。

Heroku似乎认为,捕获TERM信号并将其转换为QUIT信号是将硬关机变为正常关机的正确行为。

但是,在某些情况下,执行此操作似乎会导致完全不关机的风险-此错误的根源。遇到运行独角兽的悬挂式测功机的用户,应考虑证据并根据首要原则(而不只是文档)做出自己的决定。


2
Heroku文档仍然涵盖“ 使用SIGTERM进行的正常关机 ”,而且我看不到不再需要在Cedar堆栈上执行此操作的内容。您是否在哪里可以找到参考?
丹尼斯

我找不到任何支持此答案的文档。根据Unicorn和Heroku的文档,Unicorn仍然使用POSIX信号解释的相反方法。
乔什·科瓦奇

这不是真的。如果不明确处理TERM信号,Unicorn仍然无法正常关闭。支持此功能的开发人员中心文章可在以下位置找到:devcenter.heroku.com/articles/rails-unicorn#config
倾斜

我知道Heroku文档说您应该尝试捕获/转换这些信号。尝试正常关闭是最可能导致关闭超时的根本原因。
温菲尔德2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.