Celery: Перезапуск проблем с сельдереем и улучшение файла конфигурации супервизора

Созданный на 9 мая 2010  ·  16Комментарии  ·  Источник: celery/celery

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

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

И сегодня я думаю, что настоящая причина найдена. Значение супервизора по умолчанию для параметра «stopwaitsecs» равно 10 с. Это означает, что через 10 секунд процесс celery будет убит сигналом KILL вместо TERM. Кажется, сельдерей не любит, когда его убивают, и в этом случае пытается создать дополнительный процесс.

Поэтому я думаю, что было бы неплохо добавить что-то вроде «stopwaitsecs=600» во все файлы конфигурации примеров супервизора (из часто задаваемых вопросов: «Вы никогда не должны останавливать celeryd сигналом KILL (-9), если вы не пробовали TERM несколько несколько раз и подождал несколько минут, чтобы дать ему возможность завершить работу.") и исследовать поведение celeryd при сигнале KILL: в документах упоминается, что задачи будут потеряны (и во многих случаях это терпимо), но проблема с порожденными процесс немного странный.

Самый полезный комментарий

Если у вас по-прежнему возникают проблемы с прекращением работы ваших воркеров Celery, вы можете попробовать установить stopasgroup=true перед тем, как увеличить stopwaitsecs .

Все 16 Комментарий

Процессы, запускаемые при получении сигнала KILL , действительно странные. Я не вижу такого поведения при использовании вне supervisord , так что, может быть, это что-то из-за него?

Если вы устанавливаете модуль setproctitle , сельдерей должен сообщать о типе процесса в списках ps Не могли бы вы сделать это, чтобы выяснить, какой процесс создан?

( easy_install setproctitle )

Установка тайм-аута на 600 , вероятно, хороша. Есть ли настройка на бесконечность (может с предупреждением, если слишком долго)? Когда celeryd уничтожается с помощью TERM (что является предпочтительным сигналом завершения работы), он перестает получать сообщения и ожидает завершения текущих выполняемых задач. И я предполагаю, что для большинства приложений прерывание в середине выполнения неприемлемо.

Что касается порождения процессов: setproctitle и просмотр идентификаторов процессов были полезны. Это не порождение процесса. Рабочие процессы остаются в живых, когда родительский процесс уничтожается.
Это симуляция перезапуска супервизора с ручным уничтожением и нулевым временем ожидания:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6101 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6108 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 nadovmeste:~# kill 6101 & kill -9 6101 &

пс-афкс:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6867 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6875 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 6108 ?        S      0:00 [celeryd.PoolWorker-1]       

Я смог воспроизвести это только с такой искусственной гонкой между kill и kill -9 . Иногда работника убивают должным образом. Проблема, похоже, связана с супервизором, потому что, когда я запускаю celeryd из консоли, мне не удается его воспроизвести.

Я смог воспроизвести это с помощью запускаемых с консоли сценариев после нескольких попыток:

/home/nadovmeste/envs/nadovmeste/bin/python /home/nadovmeste/src/nadovmeste/manage.py celeryd -B --loglevel=INFO&

а затем в другом терминальном сеансе:

nadovmeste:~# ps -afx

 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash
 9343 pts/2    Sl     0:00          \_ [celeryd.MainProcess] Running... (-B --loglevel=INFO)                                                           
 9350 pts/2    S      0:00              \_ [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00              \_ [celerybeat]     

nadovmeste:~# kill 9343 & kill -9 9343

nadovmeste:~# ps -afx

 4526 ?        Ss     0:00  \_ sshd: root@pts/1 
 4529 pts/1    Ss     0:00  |   \_ -bash
 9366 pts/1    R+     0:00  |       \_ ps -afx
 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash    
 ...
 9350 pts/2    S      0:00 [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00 [celerybeat]

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

Возможно, это связано с celerybeat, потому что я смог воспроизвести проблему для celeryd, запущенного на консоли, только после использования опции -B .

Если я тестирую некоторые задачи сельдерея локально и использую параметр -B, иногда процесс не уничтожается, когда я использовал ctrl-c.

Я не могу воспроизвести это локально. Кстати, вы используете основную ветку? Я только что исправил ошибку, из-за которой могло зависнуть завершение работы. Если бы вы могли протестировать это, было бы неплохо.

Да, я запускаю последнюю основную ветку. Я видел ваш коммит по исправлению ошибок и надеялся, что он поможет, но, похоже, в моем случае он не помогает: последний сельдерей, похоже, ведет себя так же. Но не исключено, что изначальная проблема решена - проверяю это только немедленным киллом. Сейчас не могу обхватить его руками :) Проблема ctrl-c не воспроизводится с моей настройкой.

Итак, отчет об ошибке, упрощенный: http://gist.github.com/401028 . Результаты всегда одинаковы (не иногда). У меня есть некоторые периодические задачи и некоторые непериодические. Задания простые и не занимают много времени. Это ошибка, что дочерние процессы остаются в живых после убийства основного процесса? Если это так, и вы не можете воспроизвести его, то я постараюсь предоставить минимальный проект.

Поведение celerybeat при убийстве интересно: когда я убиваю зависший(?) процесс celerybeat, зависший(?) рабочий процесс также выключается.

@kmike Я все еще не могу воспроизвести приведенные выше команды. Может быть, потому что я на OS X, или, может быть, вы используете Python 2.5? (у меня 2.6.1)

Можно запустить его с --loglevel=DEBUG? Это может предоставить некоторую информацию о том, где он останавливается.

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

Я думал, что основной процесс был убит: его не видно в списке процессов. Однако у меня нет большого опыта управления процессами.

Моя установка была Debian Lenny + python 2.5.

Я попытаюсь запустить celeryd с параметром --loglevel=DEBUG и воспроизвести его на своем macbook.

хм, ты прав конечно. Это похоже на то, как процесс удара берет на себя ответственность за процессы пула.

Я только что попытался воспроизвести на Debian Lenny с python 2.5, и там все работает.
Пытался убить как TERM, так и INT.

Спрашивайте, спасибо за помощь.

Я думаю, что первоначальная проблема была решена с увеличением времени ожидания супервизора и вашей фиксацией исправления ошибок. Моделирование было неверным, потому что я использую команды kill -9 и они посылают сигнал KILL вместо TERM. С TERM сигнальные процессы убиваются должным образом.

Супервизор использует сигнал TERM, так что все должно быть в порядке.

Но меня немного пугает то, что первоначальный баг не был расследован. Постараюсь воспроизвести и дам вам знать.

Ах! Мне так жаль. Я недостаточно внимательно прочитал вопрос. Да! Это именно то, что происходит, когда вы убиваете его с помощью SIGKILL. Сигнал 9 не может быть пойман, поэтому мы ничего не можем с этим поделать, насколько я знаю.

Если у вас по-прежнему возникают проблемы с прекращением работы ваших воркеров Celery, вы можете попробовать установить stopasgroup=true перед тем, как увеличить stopwaitsecs .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги