Задачи, повторяющиеся в Celery

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

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

У меня есть один узел сельдерея с 4 рабочими (версия 3.1.23). Брокер и серверная часть результатов находятся на Redis. Я отправляю сообщения только в одну очередь и не использую celery beat.

Конфигурация в Django settings.py:

BROKER_URL = 'redis://localhost:6380'
CELERY_RESULT_BACKEND = 'redis://localhost:6380'

Соответствующая часть журнала:

[2016-05-28 10:37:21,957: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
[2016-05-28 11:37:58,005: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
[2016-05-28 13:37:59,147: INFO/MainProcess] Received task: painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647]
...
[2016-05-30 09:27:47,136: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 53.33468166703824s: None
[2016-05-30 09:43:08,317: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 466.0324719119817s: None
[2016-05-30 09:57:25,550: INFO/MainProcess] Task painel.tasks.indicar_cliente[defc87bc-5dd5-4857-9e45-d2a43aeb2647] succeeded in 642.7634702899959s: None

Задания отправляются по запросу пользователя с:

tasks.indicar_cliente.delay(indicacao_db.id)

Вот исходный код задачи и настройка службы celery.

Почему задачи поступают несколько раз через некоторое время работы службы? Как я могу получить последовательное поведение?


person rodorgas    schedule 30.05.2016    source источник
comment
Кто планирует задание? Активирован ли пользователь? крон сработал? вы используете сельдерей бить. Публиковать только в одну очередь? Вставьте конфигурацию сельдерея   -  person Mauro Rocco    schedule 31.05.2016
comment
@MauroRocco Задачи отправляются по запросу пользователя (не по расписанию, и я не использую ритм сельдерея). Я отправляю сообщения только в одну очередь. Я обновил свой вопрос, включив в него конфигурацию сельдерея и исходный код задачи.   -  person rodorgas    schedule 01.06.2016
comment
Привет, так вы говорите, что если вы запустите это локально и запланируете только одну задачу, вы увидите выполнение 3 задач? Потому что, если это запускается пользователем, то обычно задача назначается для каждого пользователя, запрашивающего ее.   -  person Mauro Rocco    schedule 01.06.2016
comment
Задачи @MauroRocco обычно следуют желаемому поведению. Однако через пару дней после запуска службы задачи приходят несколько раз (более 100 раз за короткий промежуток времени). Не похоже, что пользователи запускают задачи, потому что они получены с одним и тем же идентификатором задачи (если бы пользователи запрашивали новые задачи, в журнале были бы разные идентификаторы)   -  person rodorgas    schedule 01.06.2016
comment
Можете ли вы опубликовать код, который планирует задачу?   -  person Mauro Rocco    schedule 02.06.2016
comment
@MauroRocco Обратите внимание, что задачи не запланированы, они выполняются асинхронно с использованием метода delay(). Код, который отправляет новую задачу, и код, который обрабатывает задачи здесь   -  person rodorgas    schedule 02.06.2016


Ответы (3)


Это может быть немного устаревшим, но я столкнулся с той же проблемой и исправил ее с помощью Redis. Короче говоря, Celery некоторое время ждет выполнения задачи, и если время истекло, перезапускает задачу. Это называется тайм-аутом видимости. Объяснение из документов:

Если задача не подтверждена в течение времени ожидания видимости, задача будет повторно доставлена ​​другому работнику и выполнена. Это вызывает проблемы с задачами ETA/обратного отсчета/повторных попыток, когда время выполнения превышает время ожидания видимости; на самом деле, если это произойдет, он будет выполняться снова и снова в цикле. Таким образом, вы должны увеличить время ожидания видимости, чтобы оно соответствовало времени самого длинного ETA, которое вы планируете использовать. Обратите внимание, что Celery будет повторно доставлять сообщения при завершении рабочего процесса, поэтому длительный тайм-аут видимости задержит повторную доставку «потерянных» задач только в случае сбоя питания или принудительного завершения рабочих процессов.

Пример параметра: https://docs.celeryproject.org/en/stable/userguide/configuration.html#broker-transport-options

Подробности: https://docs.celeryproject.org/en/stable/getting-started/brokers/redis.html#visibility-timeout

person Andrey Rusanov    schedule 15.09.2018
comment
Просто чтобы добавить, может быть забавное взаимодействие с использованием acks_late. По сути, если вы установите значение true, задачи будут подтверждаться только после завершения. Это означает, что более длительные задачи могут привести к этой проблеме. Кстати, спасибо за ваш ответ здесь. Супер полезно. - person PirateNinjas; 21.11.2019

Решено с помощью брокера rabbitmq вместо Redis.

person rodorgas    schedule 11.09.2016

Я столкнулся с такой проблемой. Повышение тайм-аута видимости сельдерея было не работает.

Оказывается, я также запускал экспортер Prometheus, который создавал свой собственный объект Celery, который использовал тайм-аут видимости по умолчанию, тем самым отменяя более высокий тайм-аут, который я установил в своем приложении.

Если у вас есть несколько клиентов Celery — предназначены ли они для отправки задач, обработки задач или просто наблюдения за задачами — убедитесь, что все они имеют одинаковую конфигурацию.

person James Mishra    schedule 25.03.2021