Как правильно перезапустить Сельдерей, не откладывая задачи
Мы используем Celery с нашим Django webapp для управления автономными задачами; некоторые из этих задач могут работать до 120 секунд.
Всякий раз, когда мы делаем какие-либо модификации кода, нам нужно перезапустить Celery, чтобы перезагрузить новый код Python. Наше настоящее решение состоит в том, чтобы отправить SIGTERM в основной процесс сельдерея (kill -s 15 `cat /var/run/celeryd.pid`
), затем дождаться его смерти и перезапустить его (python manage.py celeryd --pidfile=/var/run/celeryd.pid [...]
).
Из-за долговременных задач это обычно означает, что выключение займет минуту или две, в течение которых новые задачи не обрабатываются, что вызывает заметную задержку для пользователей, находящихся на этом сайте. Я ищу способ сказать Сельдериаю о завершении работы, но затем сразу же запустит новый экземпляр Celery, чтобы начать выполнение новых задач.
Вещи, которые не выполняли:
- Отправка SIGHUP в основной процесс: это привело к тому, что сельдерей попытался "перезапустить", совершив теплое завершение, а затем снова перезапустив себя. Это не только длится долго, но даже не работает, потому что, по-видимому, новый процесс запускается до того, как старый умирает, поэтому новый жалуется
ERROR: Pidfile (/var/run/celeryd.pid) already exists. Seems we're already running? (PID: 13214)
и сразу же умирает. (Это похоже на ошибку в самом сельдерейке, я сообщит об этом.
- Отправка SIGTERM в основной процесс, а затем немедленный запуск нового экземпляра: та же проблема с Pidfile.
- Отключение Pidfile полностью: без него мы не можем сказать, какой из 30 процессов Celery является основным процессом, которому необходимо отправить SIGTERM, когда мы хотим, чтобы он сделал теплое завершение работы. У нас также нет надежного способа проверить, жив ли основной процесс.
Ответы
Ответ 1
celeryd имеет параметр --autoreload. Если включено, работник сельдерея (основной процесс) обнаружит изменения в модулях сельдерея и перезапустит все рабочие процессы. В отличие от сигнала SIGHUP, автозагрузка перезапускает каждый процесс независимо при завершении текущей исполняемой задачи. Это означает, что при перезапуске одного рабочего процесса остальные процессы могут выполнять задачи.
http://celery.readthedocs.org/en/latest/userguide/workers.html#autoreloading
Ответ 2
Недавно я исправил ошибку с помощью SIGHUP: https://github.com/celery/celery/pull/662
Ответ 3
rm *.pyc
Это приводит к перезагрузке обновленных задач. Недавно я обнаружил этот трюк, я просто надеюсь, что нет никаких неприятных побочных эффектов.
Ответ 4
Немного поздно, но это может быть зафиксировано удалением файла с именем celerybeat.pid.
Работал для меня.
Ответ 5
Вы можете запустить его с помощью пользовательского имени файла pid. Возможно, timestamped, и ключ от этого, чтобы узнать, какой PID убить?
CELERYD_PID_FILE="/var/run/celery/%n_{timestamp}.pid"
^ Я не знаю синтаксиса timestamp, но может быть, вы это сделаете или можете его найти?
то используйте текущее системное время, чтобы убить любые старые pids и запустить новый?
Ответ 6
Хорошо, вы используете SIGHUP (1) для теплой остановки сельдерея. Я не уверен, действительно ли это вызывает теплое закрытие. Но SIGINT (2) вызовет теплое закрытие. Попробуйте SIGINT вместо SIGHUP, а затем запустите сельдерей вручную в своем script (я думаю).