Я пытаюсь контролировать рабочих-единорогов с помощью monit, поэтому он изящно убивает их, когда они достигают определенного порога памяти.
Проблема:
Когда я приказываю monit перезапустить воркер, он сначала пытается его остановить, запуская мою команду сценария /etc/init.d/unicorn kill_worker 0
.
# my /etc/monit/config.d/unicorn file
check process orly_unicorn_worker_0 with pidfile /tmp/unicorn.orly.0.pid
start program = "/bin/true"
stop program = "/etc/init.d/unicorn_orly kill_worker 0"
Наблюдая за процессами с помощью команды top
, я вижу, как рабочий процесс убит и как мастер порождает нового рабочего с, конечно же, другим pid.
Однако Monit ждет некоторое время и выдает в журнал ошибку «не удалось остановить». На самом деле он ждет 30 секунд и тайм-аут.
По истечении времени ожидания monit распознает restart action is done
, а затем замечает, что рабочий PID изменился, и продолжает отслеживать процесс, как ожидалось.
В результате все работает, monit может перезапускать воркера, когда это необходимо, и продолжать следить за ним, но в журнале полно ошибок, веб-интерфейс показывает неприятный (и сбивающий с толку) статус ошибки execution failed
для воркера, и я предполагаю, что это отправили бы ошибочные оповещения по электронной почте, если бы они были настроены.
Это соответствующая часть журнала, когда я пытаюсь перезапустить воркера через веб-интерфейс (обратите внимание, как он также путается с родительским PID воркера):
[UTC Mar 5 13:29:17] info : 'orly_unicorn_worker_0' trying to restart
[UTC Mar 5 13:29:17] info : 'orly_unicorn_worker_0' stop: /etc/init.d/unicorn_orly
[UTC Mar 5 13:29:47] error : 'orly_unicorn_worker_0' failed to stop
[UTC Mar 5 13:29:47] info : 'orly_unicorn_worker_0' restart action done
[UTC Mar 5 13:29:47] error : 'orly_unicorn_worker_0' process PID changed to 13699
[UTC Mar 5 13:29:49] error : 'orly_unicorn_worker_0' process PPID changed to 0
[UTC Mar 5 13:30:19] info : 'orly_unicorn_worker_0' process PID has not changed since last cycle
[UTC Mar 5 13:30:19] error : 'orly_unicorn_worker_0' process PPID changed to 13660
[UTC Mar 5 13:30:49] info : 'orly_unicorn_worker_0' process PPID has not changed since last cycle
Мне потребовалось много времени, чтобы понять, но что здесь происходит, так это то, что рабочий погибает, а затем возрождается так быстро, что monit даже не замечает изменения.
Я предполагаю, что monit при выполнении действия остановки читает /tmp/unicorn.orly.0.pid
, чтобы получить pid процесса, а затем проверяет, существует ли этот процесс по-прежнему.
Однако, поскольку операция kill-respawn worker происходит так быстро, monit не понимает, что pid рабочего процесса изменился, и продолжает ждать смерти рабочего (отрубленного) рабочего. Затем время ожидания истекает, затем он понимает, что pid действительно изменился, и все идет как обычно.
Грязное решение, которое я нашел:
Чтобы доказать эту гипотезу, я попытался замедлить упомянутую операцию kill-respawn worker. Поэтому я отредактировал конфигурационный файл единорога, чтобы новые рабочие засыпали за несколько секунд до того, как они запишут свой новый pid в /tmp/unicorn.orly.0.pid
.
У меня так получилось:
after_fork do |server, worker|
sleep 3
# write down the new worker PID so monit can monitor it
child_pid = server.config[:pid].sub(".pid", ".#{worker.nr}.pid")
system("echo #{Process.pid} > #{child_pid}")
end
И это прекрасно сработало: птицы и цветы поют в солнечный день, веб-интерфейс теперь показывает приятный process running
статус, журналы показывают, что все идет гладко, посмотрите:
[UTC Mar 5 13:30:44] info : 'orly_unicorn_worker_0' trying to restart
[UTC Mar 5 13:30:44] info : 'orly_unicorn_worker_0' stop: /etc/init.d/unicorn_orly
[UTC Mar 5 13:30:45] info : 'orly_unicorn_worker_0' stopped
[UTC Mar 5 13:30:45] info : 'orly_unicorn_worker_0' start: /bin/true
[UTC Mar 5 13:30:46] info : 'orly_unicorn_worker_0' restart action done
Вопрос:
Есть ли метод контроля для достижения этой цели? Засыпать моих рабочих на 3 секунды - не лучшее решение. Любые идеи?
Я понимаю, что с monit это не нормальная ситуация. Мы как бы нарушили цикл перезапуска monit, так как мы не хотим, чтобы start program
monit выполнял какие-либо действия, а вместо этого позволяли главному процессу единорога обрабатывать его (как объясняется здесь: http://www.stopdropandrew.com/2010/06/01/where-unicorns-go-to-die-watching-unicorn-workers-with-monit.html)
sleep 3
дурацкий. - person kenn   schedule 24.01.2014