Как корректно перезапустить Celery без задержки задач

Мы используем 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 пытался «перезапуститься», выполняя теплое завершение работы, а затем перезапуская себя. Мало того, что это занимает много времени, это даже не работает, потому что новый процесс запускается раньше, чем умирает старый, поэтому новый жалуется ОШИБКА: Pidfile (/var/run/celeryd.pid) уже существуют. Кажется, мы уже бежим? (PID: 13214)и сразу умирает. (Это похоже на ошибку самого Celery; я сообщил им об этом.)
  • Отправка SIGTERM в основной процесс и последующий немедленный запуск нового экземпляра: та же проблема с Pidfile.
  • Полное отключение Pidfile: без него мы не сможем сказать, какой из 30 процессов Celery является основным процессом, которому нужно отправить SIGTERM, когда мы хотим, чтобы он выполнил теплое завершение работы. У нас также нет надежного способа проверить, жив ли еще основной процесс.

24
задан Martey 12 June 2012 в 14:17
поделиться