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