Сельдерей с Upstart - процессы умирают неожиданно
Когда я запускаю Celery с Upstart, через некоторое время дочерние процессы или основные процессы умирают без следа.
Скрипт Upstart, который я использую (/etc/init/celery
):
description "celery"
start on runlevel [2345]
stop on runlevel [!2345]
kill timeout 20
# console log
setuid ***
setgid ***
script
chdir /opt/***/project/
exec /opt/***/virtualenvs/***/bin/python manage.py celery worker --settings=settings.staging -B -c 4 -l DEBUG
end script
respawn
При запуске точно такой же команды без запуска (запуск вручную exec
часть) все отлично работает.
С respawn
stanza, главный процесс умрет и возродится, пока потерянные дочерние процессы все еще существуют, вызывая переполнение памяти. Без этого процессы просто исчезнут, пока не останется рабочих.
Сельдерей порождает основной процесс и рабочие процессы (4 из них в данном случае). Я также попытался запустить его с eventlet
вместо многопроцессорной обработки (1 мастер, 1 дочерний процесс), но результаты аналогичны.
Кто-нибудь раньше воспринимал такое поведение?
Обновить:
- Сельдерей при запуске с
-c N
начинается сN + 2
процессы,N
из которых рабочие (какие еще 2?). - Я начинаю думать, что это связано с
expect
строфа, но не уверен, какое значение должно быть. Сeventlet
expect fork
имеет смысл. Но как насчет многопроцессорности?
Update2:
С помощью except fork
казалось, остановить процесс от умирания, но при попытке остановить или перезапустить работу он просто зависает.
2 ответа
С помощью chdir
внутри script
Предложение совершенно неверно, и это означает, что вы не понимаете основную идею в выскочке (без обид). (Как примечание, exec
Ключевое слово просто бесполезно, но не вредит).
Существует идея, которая имеет ключевое значение для понимания того, как работает выскочка. Upstart пытается определить, какой процесс процессов, порожденных script
Станса - это настоящий демон этой службы. Затем он использует этот процесс, чтобы определить, выполняется ли это задание, остановлено или не выполнено или что-то еще. По этой причине крайне важно убедиться в правильности процесса.
Алгоритм определения процесса очень прост, он зависит от expect
строфа. expect fork
означает "взять вторую вилку в script
строфа", expect daemon
- то же самое, но третий.
Теперь, используя chdir
внутри script
означает, что это вызывает фактическое /bin/chdir
бинарный, и это считается отдельной вилкой. Что вам нужно сделать, это переместить его за пределы script
строфа и чем играть с expect
строфа, пока вы не поняли это правильно. Вы можете проверить, правильно ли вы поняли, сравнив вывод initctl status celery
против ps
, PID должны совпадать.
Решение состояло не в том, чтобы запустить Celery beat вместе с рабочим (удаление -B
часть из команды exec).
По-видимому, это был "лишний" процесс, и он как-то все испортил.
Вот последний сценарий, с которым я закончил:
description "celery"
start on started postgresql
stop on runlevel [!2345]
kill timeout 20
setuid ***
setgid ***
respawn
chdir /opt/***/project/
exec /opt/***/virtualenvs/***/bin/python manage.py celery worker --settings=settings.staging -c 4 -l DEBUG
И работает celery beat
по отдельности:
description "celerybeat"
start on started celery
stop on stopped celery
setuid ***
setgid ***
respawn
chdir /opt/***/project/
exec /opt/***/virtualenvs/***/bin/python manage.py celery beat --settings=settings.staging -l DEBUG