2016-05-18 3 views
15

Поскольку Celery documentation заявляет, что уже выполняемая задача не будет отменена вызовом .revoke(), если не установлено terminate=True. Но это не рекомендуется, потому что он убьет самого работника, который, возможно, уже запустил другую задачу. Означает ли это, что нет надежного и стабильного способа сделать это?Есть ли способ ненасильственно остановить конкретную задачу работника сельдерея?

EDIT: celery.contrib.abortable меня не устраивает, потому что, как говорится в документации, он работает только с базами данных.

+0

Это зависит от задачи, которую вы пытаетесь прекратить (сеть, файл, операции с базами данных и т.д.), пожалуйста, обратите внимание на этот пример: http://stackoverflow.com/questions/37039941/celery- python-revoke В моем случае моя основная задача вызывает дочерние процессы, которые не завершаются, если я не отправлю сигнал SIGKILL. – spicyramen

+0

Возможный дубликат [Прекрасная задача сельдерея изящно] (http://stackoverflow.com/questions/16493364/stopping-celery-task-gracefully) – Louis

ответ

2

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

Вы можете попытаться поэкспериментировать с вашей собственной реализацией обработки событий отзыва, пытаясь выяснить идентификатор подпроцесса и убить только тот, но, честно говоря, не знаете, стоит ли и действительно ли он может работать.

Я думаю, что короткий ответ - вы не можете.

В любом случае убийство работника необходима иногда, особенно в начальных стадиях проектов, в которых вы все еще нужно правильно размерности ресурсы, просто убедитесь, что вы входите где-то запущенные задачи, так что вы можете перенести их или просто использовать CELERY_ACKS_LATE

+0

«Во всяком случае, убийство рабочего не является необычным». Что * обычно * условие гарантировало бы насильственное прекращение работника на производственной системе? Я использовал Сельдерей в течение нескольких лет, и только * время, когда рабочий принудительно прекращается, когда сайт должен быть закрыт для обслуживания. – Louis

+1

Зависит от прецедента, я работаю на большом веб-сайте сообщества в те дни, и мы получили некоторые проблемы в часы пик. Рабочие занимали много памяти и замерзали. Конечно, это было связано с тем, что мы не ожидали, что груз и работник не будут правильно рассчитаны. Но могу вам сказать, что через год прошло пару раз, не учитывая полного крушения машины из-за других факторов. –

+0

Я разъяснил ответ после комментария Луи. –

1

Вы можете отправить сигнал HUP вместо TERM, который изящно перезапускает дочерний процесс, не убивая рабочего.

In [80]: import signal 

In [81]: x = add.delay(1, 2) 

In [82]: x.revoke(terminate=True, signal=signal.SIGHUP) 
+0

«За исключением остановки, а затем перезапуска рабочего, вы также можете перезапустить рабочего, используя сигнал HUP, но обратите внимание, что работник будет нести ответственность за перезагрузку, поэтому это подвержено проблемам и не рекомендуется в процессе производства» [Source] (http://docs.celeryproject.org/en/latest/userguide/workers.html) – Louis

+0

@Louis Если у вас есть рабочий с параллелизмом 4, он имеет 4 процесса, выполняющих 4 задачи за раз. Теперь перезапуск - это плохая идея просто отозвать задачу, поскольку она может прервать другой процесс. Вышеупомянутая команда перезапустит только один процесс, который выполнял эту задачу. – ChillarAnand

Смежные вопросы