Избегайте повторных попыток Celery для незарегистрированной задачи

У нас есть приложение Django с celery для обработки асинхронных задач. Мы используем AWS SQS в качестве брокера задач.

В итоге мы получили плохо обрабатываемую задачу (удалили реализацию задачи, не удалив запись celery-beat). Это привело к ошибкам:

Received unregistered task of type KeyError('some_deleted_task').
The message has been ignored and discarded.

После очистки записей celery-beat мы продолжали получать ошибки ~2 минуты (таймаут видимости на SQS был установлен на 2 минуты).

Поведение выглядело следующим образом:

  1. Task added to queue, in SQS as 'Available'
  2. Worker picks up the task, moves the SQS message to 'in flight'
  3. Worker fails immediately due to missing implementation.
  4. two minutes later, SQS moves the message from 'in flight', back to 'available'
  5. Goto 2

Чтобы устранить ошибки, мы очистили очередь SQS, но это могло привести к потере других задач.

Я бы хотел настроить celery так, чтобы он не продолжал бесконечно пытаться выполнить эти отсутствующие задачи.

Celery не делает ничего, чтобы активно повторить задание. Как указано в сообщении, задача игнорируется. Задача была поставлена в очередь, и, что вполне разумно, celery не удалит ее из очереди, пока не выполнит задачу, связанную с сообщением. Наблюдаемое вами поведение правильно и желательно.

Вы не хотите, чтобы получение незарегистрированной задачи приводило к удалению сообщения из очереди, поскольку это может привести к потере сообщений. Например, если вы развертываете новую версию вашего приложения с новой задачей, но старый рабочий все еще активен (что происходит практически при всех развертываниях с нулевым временем простоя), старая версия может получать сообщения от новой версии, и она будет считать, что получила незарегистрированную задачу. Если бы celery удалял сообщения при встрече с незарегистрированными задачами, это могло бы привести к потере этих сообщений, среди прочих подобных случаев.

Вернуться на верх