Таймаут выхода Unicorn на Heroku после захвата TERM и отправки QUIT

90

Я получаю ошибки времени ожидания выхода R12 для приложения Heroku, на котором запущены unicorn и sidekiq. Эти ошибки возникают 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

Похоже, что все дочерние процессы были успешно получены до истечения времени ожидания. Возможно ли, что хозяин еще жив? Кроме того, должен ли маршрутизатор по-прежнему отправлять веб-запросы на дино во время выключения, как показано в журналах?

FWIW, я использую плагин развертывания Heroku с нулевым временем простоя ( https://devcenter.heroku.com/articles/labs-preboot/ ).

Middkidd
источник
6
Если это поможет, я также испытываю эту проблему без подключаемого модуля развертывания с нулевым временем простоя. Я надеюсь, что кто-то может помочь, или вы можете опубликовать ответ, если разберетесь. Возможно, обратитесь в службу поддержки Heroku?
Крис Питерс
Как и Крис, я не использую нулевое время простоя, и у меня возникла эта проблема. Это несмотря на использование конфигурации единорога, рекомендованной Heroku.
imderek
У меня такая же проблема, несмотря на использование рекомендованной Heroku конфигурации. Также нет развертывания с нулевым временем простоя.
elsurudo 07
Здесь та же проблема, но без использования плагина предварительной загрузки.
Адриан Макнейл 08
Я заметил одну вещь: это ОБЫЧНО происходит на рабочих динамометрических станциях. Не всегда, но обычно.
Крис Питерс,

Ответы:

4

Я думаю, что ваша индивидуальная обработка сигналов является причиной тайм-аутов здесь.

РЕДАКТИРОВАТЬ: Меня отвергают за несогласие с документацией Heroku, и я хотел бы заняться этим.

Настройка приложения Unicorn для перехвата и приема сигнала TERM является наиболее вероятной причиной зависания вашего приложения и некорректного завершения работы.

Похоже, Heroku утверждает, что перехват и преобразование сигнала TERM в сигнал QUIT - это правильное поведение, позволяющее превратить принудительное завершение работы в плавное завершение работы.

Однако в некоторых случаях это может привести к тому, что вы не завершите работу вообще, что является корнем этой ошибки. Пользователи, которые сталкиваются с зависающими динамометрическими станциями с Unicorn, должны учитывать доказательства и принимать собственное решение, основываясь на основных принципах, а не только на документации.

Winfield
источник
2
Документация Heroku по-прежнему охватывает « Изящное завершение работы с помощью SIGTERM », и я не вижу упоминания о том, что больше не нужно этого делать в стеке Cedar. У вас есть ссылка, где это можно найти?
Деннис
Я не могу найти никакой документации, подтверждающей этот ответ. Согласно документации Unicorn и Heroku, Unicorn по-прежнему использует обратную интерпретацию сигнала POSIX.
Джош Ковач
Это неправда. Unicorn по-прежнему не завершается корректно без явной обработки сигнала TERM. В статье Dev Center поддерживает это можно найти здесь: devcenter.heroku.com/articles/rails-unicorn#config
скос
Я понимаю, что документы Heroku говорят, что вы должны попытаться поймать / преобразовать эти сигналы. Попытки корректного завершения работы являются наиболее вероятной основной причиной тайм-аутов завершения работы.
Winfield