Я правильно загружаю приложение в Heroku + Unicorn? - PullRequest
7 голосов
/ 19 февраля 2012

При использовании Unicorn на Heroku. При масштабировании возникнут проблемы, поскольку недавно масштабированные веб-динамометры могут быть доступны по запросу, когда приложение все еще загружается. Что в основном приводит к ошибке тайм-аута.

Я немного прочитал в http://codelevy.com/2010/02/09/getting-started-with-unicorn.html и https://github.com/blog/517-unicorn

В двух статьях предлагается использовать preload_app true. И after_fork и before_fork блок.

В Rails 3+ код в before_block все еще требуется? Я где-то читал, иначе. Кто-нибудь, кто уже сталкивался с этим и хотел бы поделиться?

Я что-то упустил? Я правильно загружаю приложение?

# config/initializers/unicorn.rb
# Read from:
# http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/
worker_processes 3 # amount of unicorn workers to spin up
timeout 30         # restarts workers that hang for 90 seconds

# Noted from http://codelevy.com/2010/02/09/getting-started-with-unicorn.html
# and https://github.com/blog/517-unicorn
preload_app true

after_fork do |server, worker|
  ActiveRecord::Base.establish_connection
end

before_fork do |server, worker|
  ##
  # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
  # immediately start loading up a new version of itself (loaded with a new
  # version of our app). When this new Unicorn is completely loaded
  # it will begin spawning workers. The first worker spawned will check to
  # see if an .oldbin pidfile exists. If so, this means we've just booted up
  # a new Unicorn and need to tell the old one that it can now die. To do so
  # we send it a QUIT.
  #
  # Using this method we get 0 downtime deploys.

  old_pid = Rails.root + '/tmp/pids/unicorn.pid.oldbin'
  if File.exists?(old_pid) && server.pid != old_pid
    begin
      Process.kill("QUIT", File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
end

Ответы [ 3 ]

2 голосов
/ 16 июля 2012

Только частичный ответ, но мне удалось сократить эти неприятные таймауты масштабирования с помощью этой конфигурации Unicorn:

worker_processes 3 # amount of unicorn workers to spin up
timeout 30         # restarts workers that hang for 30 seconds
preload_app true

# hack: traps the TERM signal, preventing unicorn from receiving it and performing its quick shutdown.
# My signal handler then sends QUIT signal back to itself to trigger the unicorn graceful shutdown
# http://stackoverflow.com/a/9996949/235297
before_fork do |_server, _worker|
  Signal.trap 'TERM' do
    puts 'intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end
end

# Fix PostgreSQL SSL error
# http://stackoverflow.com/a/8513432/235297
after_fork do |server, worker| 
  defined?(ActiveRecord::Base) and 
  ActiveRecord::Base.establish_connection 
end

Кроме того, я использую heroku labs:enable preboot (см. https://devcenter.heroku.com/articles/labs-preboot/). К сожалению, я все еще вижу некоторые тайм-ауты при масштабировании веб-динос.

Вот обсуждение, которое я инициировал на форуме поддержки HireFire: http://hirefireapp.tenderapp.com/discussions/problems/205-scaling-up-and-down-too-quickly-provoking-503s

2 голосов
/ 16 июня 2017

preload_app true помогло для нашего приложения, поэтому сделайте это, если вы видите проблемы с таймаутами во время развертывания / перезагрузки. Комментарии о том, что это не помогает, заставили меня подумать, что не стоит пытаться, а затем поняли, что это действительно то исправление, в котором мы нуждались.

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

Мы поняли, что с preload_app false Unicorn сначала свяжет свой порт, а затем загрузит приложение. Как только он связывает порт, Heroku начинает отправлять ему трафик. Но затем это медленное приложение загружается слишком долго, так что трафик получает тайм-ауты.

Это легко проверить, запустив Unicorn в dev, попытавшись получить доступ к сайту сразу после запуска Unicorn и проверив, есть ли у вас ошибка типа «нет сервера на этом порту» (желательно) или очень медленный запрос (нежелательно) ).

Когда мы вместо этого устанавливаем preload_app true, тогда потребуется больше времени, чтобы Unicorn связал порт, но как только это произойдет, и Heroku отправит ему трафик, он будет готов ответить.

2 голосов
/ 20 февраля 2012

То, что вы видите здесь, ожидается.В тот момент, когда вы увеличиваете масштаб с помощью динамометра, платформа Heroku развернет этот слаг на новом динамо, которое полностью изолировано от других ваших динамов (то есть другого мастера-единорога).эффективно загружается), сетка маршрутизации начнет посылать запросы этому dyno, когда Rails будет запущен на Unicorn или любом другом сервере, который вы настроили.

Однако, как только этот запрос поступит, вы получите30-секундное окно для возврата ваших данных или запрос будет задержан в сетке маршрутизации (ошибка H12).

Таким образом, если подвести итог, ваша проблема не связана с разветвлением, это то, что ваше приложение не можетзапустить в течение 30 секунд, отсюда и ранние таймауты.Беспокойство по поводу разветвления и PID-файлов - это не то, о чем вам нужно беспокоиться на платформе Heroku.

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