Используя Выскочку для управления Единорогом w/rbenv + bundler binstubs w/хижина рубинового локального должностного лица

Мы работаем над выполнением этой самой вещи в Национальных Инструментах. Можно читать больше о том, что мы делаем по http://dev2ops.org/blog/2010/4/27/qa-ernest-mueller-on-bringing-agile-to-operations.html

Соединение инструментов, что упоминания cagenut здесь в основном входят в направление, что мы приближаемся здесь.

5
задан 29 December 2011 в 13:33
3 ответа

В самом деле, ограничение выскочки состоит в том, что он не может отслеживать демонов, которые делают то, что делает единорог ... то есть fork / exec, и завершают свой основной процесс. Вы не поверите, но sshd делает то же самое с SIGHUP, и, если вы посмотрите, /etc/init/ssh.conf гарантирует, что sshd работает на переднем плане. Это также одна из причин, по которой apache2 по-прежнему использует сценарий init.d.

Похоже, Gunicorn фактически демонизирует себя при получении SIGUSR1 путем разветвления и последующего выхода. Это могло бы сбить с толку любого из менеджеров процессов, которые пытаются поддерживать процесс.

Я думаю, у вас есть два варианта. 1 - просто не использовать SIGUSR1 и останавливать / запускать gunicorn, когда он вам нужен.

Другой вариант - не использовать отслеживание pid выскочки, а просто сделать следующее:

start on ..
stop on ..

pre-start exec gunicorn -D --pid-file=/run/gunicorn.pid
post-stop exec kill `cat /run/gunicorn.pid`

Не так привлекательно, как отслеживание pid, но по крайней мере Ты победил'

3
ответ дан 3 December 2019 в 01:10

Я выбрал немного другое решение, чем SpamapS .. Я также запускаю приложение с preload_app = true, управляемое Upstart.

Когда я искал сам решить эту проблему, я Я использовал "exec" Upstart для запуска моего приложения ("exec bundle exec unicorn_rails бла-бла"). Затем я нашел ваш вопрос, и он заставил меня понять, что вместо использования «exec» Upstart для указания моего исполняемого файла я мог бы использовать раздел сценария, который будет запускаться в отдельном процессе, процесс, который будет наблюдать Upstart.

Итак, мой конфигурационный файл Upstart включает следующее:

respawn

script
  while true; do
    if [ ! -f /var/www/my_app/shared/pids/unicorn.pid ]; then
      # Run the unicorn master process (this won't return until it exits).
      bundle exec unicorn_rails -E production -c /etc/unicorn/my_app.rb >>/var/www/my_app/shared/log/unicorn.log
    else
      # Someone restarted the master; wait for the new master to exit.
      PID=`cat /var/www/my_app/shared/pids/unicorn.pid`
      while [ -d /proc/$PID ]; do
        sleep 2
      done
      # If we get here, the master has exited, either because someone restarted
      # it again (in which case there's already a new master running), or
      # it died for real (in which case we'll need to start a new process).
      # The sleep above is a tradeoff between polling load and mimizing the
      # restart delay when the master dies for real (which should hopefully be
      # rare).
    fi
  done
end script

before_fork в моем конфигурационном файле Unicorn точно такой же, как предложено в примере с сайта unicorn, http://unicorn.bogomips.org/examples/unicorn.conf. rb :

before_fork do |server, worker|
  ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord::Base)

  old_pid = '/var/www/my_app/shared/pids/unicorn.pid.oldbin'
  if server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
      # someone else did our job for us
    end
  end
  sleep 0.5
end

Итак: при запуске сценарий Upstart не t найти pid-файл, поэтому он запускает unicorn_rails, который продолжает работать.

Позже мы повторно развертываем наше приложение, и задача Capistrano запускает перезапуск приложения через:

kill -USR2 `cat /var/www/my_app/shared/pids/unicorn.pid`

Это говорит старому мастеру Unicorn запустить новый мастер-процесс Unicorn, и когда новый мастер запускает рабочие процессы, блок Unicorn before_fork отправляет сигналы TTOU старому мастеру, чтобы выключить старые рабочие (изящно), а затем QUIT, когда остается только один рабочий.

Этот QUIT вызывает выход старого мастера (но только когда новые рабочие уже обрабатывают нагрузку), поэтому "bundle exec unicorn_rails" возвращается в скрипте unicorn. Затем этот сценарий зацикливается, видит существующий файл pid и ожидает завершения процесса. Он не выйдет до следующего развертывания, но, если это произойдет, мы вернемся снова; мы также будем повторять цикл каждый раз, когда мастер умирает.

7
ответ дан 3 December 2019 в 01:10

Согласно документации выскочки , вы можете указать выскочке не отправлять сигналы TERM и KILL службе с помощью говоря это в вашем блоке pre-stop . Все, что вам нужно сделать, это сказать start в вашем pre-stop , и он прервет отправку сигнала.

Вместе с трюком выше Брайана, который выяснил, что ] скрипт также может включать бесконечный цикл и не быть фактическим процессом единорога - я создал пример, который работает с использованием этой техники.

Пример довольно простой, он обрабатывает отправку USR2 , когда бегущий выскочка стоп единорог . И он также возродит нового единорога, если по какой-то причине все единороги умерли сами по себе.

Код и результаты тестов находятся здесь - https://gist.github.com/kesor/6255584

0
ответ дан 3 December 2019 в 01:10

Теги

Похожие вопросы