Как перезапустить Celery изящно, не затягивая задачи - PullRequest
24 голосов
/ 10 марта 2012

Мы используем Celery с нашим веб-приложением Django для управления автономными задачами;некоторые из этих задач могут выполняться до 120 секунд.

Всякий раз, когда мы вносим какие-либо изменения в код, нам нужно перезапустить Celery, чтобы он перезагрузил новый код Python.Наше текущее решение - отправить SIGTERM в основной процесс Celery (kill -s 15 `cat /var/run/celeryd.pid`), затем дождаться его смерти и перезапустить (python manage.py celeryd --pidfile=/var/run/celeryd.pid [...]).

Из-за длительных задач этообычно означает, что завершение работы займет одну или две минуты, в течение которых новые задачи не обрабатываются, что вызывает заметную задержку для пользователей, которые в настоящее время находятся на сайте.Я ищу способ заставить Celery завершить работу, но затем немедленно запустить новый экземпляр Celery, чтобы запустить новые задачи.

Вещи, которые не работали:

  • Отправка SIGHUP основному процессу: это заставило Celery попытаться «перезапустить», сделав теплое завершение работы и затем перезапустив себя.Мало того, что это занимает много времени, это даже не работает, потому что, очевидно, новый процесс запускается до того, как старый умирает, поэтому новый жалуется ERROR: Pidfile (/var/run/celeryd.pid) already exists. Seems we're already running? (PID: 13214) и умирает немедленно.(Это похоже на ошибку в самом Celery; я дал им знать об этом.)
  • Отправка SIGTERM в основной процесс и затем немедленный запуск нового экземпляра: та же проблема сPidfile.
  • Полное отключение Pidfile: без него мы не сможем сказать, какой из 30 процессов Celery является основным процессом, который необходимо отправить в SIGTERM, когда мы хотим, чтобы он выполнял горячее отключение.У нас также нет надежного способа проверить, если основной процесс еще жив.

Ответы [ 7 ]

4 голосов
/ 10 марта 2012

celeryd имеет опцию --autoreload. Если этот параметр включен, работник сельдерея (основной процесс) обнаружит изменения в модулях сельдерея и перезапустит все рабочие процессы. В отличие от сигнала SIGHUP, автозагрузка перезапускает каждый процесс независимо, когда текущая задача завершается. Это означает, что пока один рабочий процесс перезапускает, остальные процессы могут выполнять задачи.

http://celery.readthedocs.org/en/latest/userguide/workers.html#autoreloading

3 голосов
/ 31 мая 2012

Я недавно исправил ошибку с SIGHUP: https://github.com/celery/celery/pull/662

2 голосов
/ 26 апреля 2013
rm *.pyc

Это приводит к перезагрузке обновленных задач. Я обнаружил этот трюк недавно, я просто надеюсь, что нет никаких неприятных побочных эффектов.

1 голос
/ 10 декабря 2014

Немного поздно, но это можно исправить путем удаления файла с именем celerybeat.pid .

работал для меня.

0 голосов
/ 08 июня 2018

Я думаю, вы можете попробовать это:

kill -s HUP ``cat /var/run/celeryd.pid`` 
python manage.py celeryd --pidfile=/var/run/celeryd.pid

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

Я использовал этот способ в нашем производстве, и теперь это кажется безопасным.Надеюсь, это поможет вам!

0 голосов
/ 21 июля 2013

Хорошо, вы используете SIGHUP (1) для теплого отключения сельдерея. Я не уверен, что это на самом деле вызывает горячее отключение. Но SIGINT (2) может вызвать горячее отключение. Попробуйте SIGINT вместо SIGHUP, а затем запустите сельдерей вручную в вашем скрипте (я думаю).

0 голосов
/ 10 марта 2012

Можете ли вы запустить его с пользовательским именем файла pid. Возможно, отметка времени и ключ от этого, чтобы узнать, какой PID убить?

CELERYD_PID_FILE="/var/run/celery/%n_{timestamp}.pid"

^ Я не знаю синтаксис отметки времени, но, может быть, вы знаете или можете его найти?

затем использовать текущее системное время, чтобы убить все старые пиды и запустить новый?

...