Как я могу сказать единорогу понять сигналы Героку? - PullRequest
9 голосов
/ 07 марта 2012

Возможно, вы видели это ...

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

Это хорошо известная проблема при запуске единорог на heroku ...

Могу ли я сказать herokuотправить SIGQUIT?Или я могу сказать единорогу относиться к SIGTERM как к грациозному отключению?

Ответы [ 2 ]

9 голосов
/ 05 марта 2013

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
6 голосов
/ 03 апреля 2012

Это хак, но я успешно создал файл конфигурации единорога, который перехватывает сигнал 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), но это просто избыточно и ни на что не повлияет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...