Долго выполняемые задачи отменяются - Celery5.2.6
У меня есть проект, размещенный в Digital Ocean в базовом дроплете с 2 ГБ Ram. На моей локальной машине долгоиграющая задача выполняется в течение 8-10 минут и все равно успешно. Однако в дроплетах Digital Ocean часто сельдерей не справляется с долгоиграющей задачей.
Текущий сельдерей - celery 5.2.6
У меня есть две конфигурации в supervisor
- Бегущий сельдерей рабочий
celery -A myproject worker -l info
- Запускаем сельдерейный бич
celery -A myproject beat -l info
Это сообщение из celeryd.log
CPendingDeprecationWarning: В Celery 5.1 мы ввели необязательное разрывное изменение, которое при подключении, потеря отменяет все выполняемые в данный момент задачи с включенным поздним подтверждением. Эти задания не могут быть подтверждены, так как соединение потеряно, и задания автоматически пересылаются обратно в очередь. Вы можете включить это поведение с помощью параметра worker_cancel_long_running_tasks_on_connection_loss. В Celery 5.1 по умолчанию установлено значение False. В Celery 6.0 эта настройка по умолчанию будет иметь значение True.
.
warnings.warn(CANCEL_TASKS_BY_DEFAULT, CPendingDeprecationWarning)
[2022-07-07 04:25:36,998: ERROR/MainProcess] consumer: Cannot connect to redis://localhost:6379//: Error 111 connecting to localhost:6379. Connection refused..
Trying again in 2.00 seconds... (1/100)
[2022-07-07 04:25:39,066: ERROR/MainProcess] consumer: Cannot connect to redis://localhost:6379//: Error 111 connecting to localhost:6379. Connection refused..
Trying again in 4.00 seconds... (2/100)
Для временного решения я сделал следующее: перезапустил сервер и заново запустил новые задачи, но это не гарантирует, что давно запущенная задача будет успешной, проблема в том, что ранее провалившаяся задача не будет перезапущена.
Моя цель,
- Предотвращение отмены давно выполняющихся задач
- Если долго выполняющаяся задача уже отменена и отмены нельзя избежать, мне нужно, чтобы она была повторно запущена и продолжена вместо того, чтобы начинать новую задачу.
Возможно ли это? Есть идеи, как это сделать?
Как указано в предупреждении, вы можете управлять этим поведением с помощью worker_cancel_long_running_tasks_on_connection_loss
, чтобы предотвратить отмену задания при потере соединения. В вашей версии celery эта функция по умолчанию выключена, поэтому ваши задачи не должны отменяться. Однако, даже если задание с поздним подтверждением успешно завершится в этом сценарии, оно все равно будет повторно доставлено в очередь и будет запущено снова - это происходит независимо от данной настройки и неизбежно для заданий с поздним подтверждением.
Вот почему жизненно важно, чтобы ваши задачи были idempotent.
Если ваша работа не является идемпотентной, альтернативным решением может быть раннее подтверждение выполнения заданий (по умолчанию), но в этом случае существует риск того, что вы можете бросить задание, не завершив его на самом деле.
Если вы должны избегать падения задач, вы должны установить acks_late=True
для вашей задачи, и она должна быть спроектирована так, чтобы быть идемпотентной. Это необходимо независимо от конкретной проблемы потери соединения, так как может произойти много других вещей, которые прервут ваши задачи и приведут к такому же сценарию.
Мне нужно, чтобы она повторно выполнялась и продолжалась, а не начинала новую задачу.
Это зависит от того, как спроектировать задание для обеспечения идемпотентности. Например, вы можете захотеть, чтобы задание отслеживало свой прогресс в постоянном хранилище, чтобы при сбое и повторном запуске задания оно могло определить, как лучше восстановиться.