Я изначально задавал этот вопрос на StackOverflow. Потом понял, что это, наверное, лучшее место.
У меня есть настройка bluepill для мониторинга моих процессов delayed_job. (Приложение Ruby On Rails)
Использование Ubuntu 12.10.
Я запускаю и отслеживаю сам сервис bluepill с помощью Ubuntu upstart
. Моя выскочка конфигурации ниже ( /etc/init/bluepill.conf
).
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
Я также пытался с expect fork
вместо expect daemon
. Я также попытался удалить expect...
линию полностью.
Когда машина загружается, bluepill запускается нормально.
$ ps aux | grep blue
root 1154 0.6 0.8 206416 17372 ? Sl 21:19 0:00 bluepilld: <app_name>
PID процесса bluepill здесь 1154. Но, upstart
кажется, отслеживает неправильный PID. Он отслеживает PID, который не существует.
$ initctl status bluepill
bluepill start/running, process 990
Я думаю, что это отслеживает PID sudo
процесса, который запустил процесс bluepill.
Это предотвращает возрождение процесса bluepill, если я принудительно убью bluepill с помощью kill -9
.
Более того, я думаю, что из-за неправильного отслеживания PID перезагрузка / завершение работы просто зависает, и мне приходится каждый раз выполнять полную перезагрузку машины.
В чем может быть проблема здесь?
ОБНОВЛЕНИЕ :
Проблема остается на сегодня (3 мая 2015 года) на Ubuntu 14.04.2.
Проблема не в использовании sudo. Я больше не использую sudo. Моя обновленная конфигурация выскочки:
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
expect daemon
script
shared_path=/home/deploy/websites/some_app/shared
bluepill load $shared_path/config/delayed_job.bluepill
end script
Когда машина загружается, программа загружается нормально. Но выскочка все еще отслеживает неправильный PID, как описано выше.
Обходной путь, упомянутый в комментариях, может исправить проблему зависания. Я не пробовал, хотя.
ps aux | grep 990
должен сделать это, ноpstree 990
может быть более информативным.Ответы:
Довольно поздно, но, надеюсь, это может помочь другим пользователям.
В upstart есть задокументированная ошибка, которая может привести к тому, что initctl отследит неверный PID, если указать неверный
fork
раздел в конфигурации upstart: https://bugs.launchpad.net/upstart/+bug/406397.Что происходит, так это то, что upstart проверяет
fork
раздел и определяет, сколько разветвленных процессов он должен проверить, прежде чем выбрать «истинный» PID контролируемой программы. Если вы укажетеexpect fork
или,expect daemon
но ваша программа не разветвляется достаточное количество раз,start
зависнет. Если, с другой стороны, ваш процесс разветвляется слишком много раз, онinitctl
будет отслеживать неправильный PID. Теоретически, это должно быть задокументировано в этом разделе готовой поваренной книги , но, как вы можете видеть в этой ситуации, есть PID, связанный с уничтоженным процессом, когда его не должно быть.Последствия этого объясняются в комментариях к багтрекеру, но я здесь подведу итог: помимо
initctl
неспособности остановить процесс демона и застрять в недокументированном / недопустимом состоянии<service> start/killed, process <pid>
, если процесс, принадлежащий этому PID, останавливается (и обычно это будет ) затем PID освобождается для повторного использования системой.Если вы введете
initctl stop <service>
илиservice <service> stop
,initctl
убьет этот PID в следующий раз, когда он появится. Это означает, что где-то в будущем, если вы не перезагрузите компьютер после этой ошибки, следующий процесс, использующий этот PID, будет немедленно уничтожен,initctl
даже если он не будет демоном. Это может быть что-то простоеcat
или сложноеffmpeg
, и вам будет трудно понять, почему ваш программный пакет завис в середине какой-то рутинной операции.Таким образом, проблема заключается в том, что вы указали неправильную
expect
опцию для числа форков, которые фактически делает процесс демона. Они говорят, что есть переписывание выскочки, которое решает эту проблему, но по состоянию на выстреле 1.8 (последняя версия Ubuntu 13.04 / январь 2014) проблема все еще присутствует.Поскольку вы использовали
expect daemon
и в конечном итоге с этой проблемой, я рекомендую попробоватьexpect fork
.Редактирование: Вот Ubuntu BASH-совместимый скрипт ( оригинальный Wade Fitzpatrick, модифицированный для использования Ubuntu
sleep
), который порождает процессы до тех пор, пока не будет исчерпано доступное адресное пространство идентификатора процесса, после чего он начинается с 0 и продолжается до «зависания» PID. Затем процесс запускается при зависании PIDinitctl
, иinitctl
убивает его и сбрасывает.источник
Для приведенного примера:
быстрое решение для меня это:
источник: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37
Я надеюсь, что это будет полезно. Что происходит, объясняется в других ответах.
источник
reboot
Иногда может быть предпочтительным , а также фиксирует это.Если вы не запускаете задание уровня пользователя Upstart или не используете раздел setuid - тогда ваша работа выполняется от имени пользователя root.
Поскольку Upstart уже запущен от имени пользователя root, зачем вам вообще использовать sudo в вашем
exec
разделе?Использование
sudo
илиsu
вexec
строфе вызвало те же проблемы для меня, как вы описали здесь.Обычно я испытываю пункт 1 ИЛИ 1 и 2:
Конечно, дополнительно вы должны указывать в
expect
строфе правильное количество вилок.YMMV, но для меня:
exec
строфе с указанным правильным количеством вилок обычно приводит к ситуации 1 выше.exec
) приводит к ситуации 1 И 2 выше.источник