Мы используем 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, когда мы хотим, чтобы он сделал теплое завершение работы. У нас также нет надежного способа проверить, жив ли основной процесс.