self.retry() вручную или настроить автоматические повторы с увеличивающейся задержкой и случайным разбросом времени.
Как реализовать retry для задачи Celery?
Подробный ответ
Когда нужен повтор
Повторять стоит только временные ошибки, когда есть разумное ожидание, что следующая попытка может завершиться успешно. Например, timeout внешнего API, временный ответ 503 или кратковременная проблема сети.
Ручной retry
from celery import shared_task
@shared_task(bind=True, max_retries=5)
def send_invoice(self, invoice_id: int) -> None:
try:
invoice = get_invoice(invoice_id)
provider.send_invoice(invoice)
except TemporaryProviderError as error:
raise self.retry(
exc=error,
countdown=60,
)Автоматический retry
from celery import shared_task
@shared_task(
autoretry_for=(TemporaryProviderError,),
retry_backoff=True,
retry_backoff_max=600,
retry_jitter=True,
max_retries=5,
)
def send_invoice(invoice_id: int) -> None:
invoice = get_invoice(invoice_id)
provider.send_invoice(invoice)Увеличивающаяся задержка
Увеличивающаяся задержка между попытками означает, что пауза постепенно растёт: например 1, 2, 4, 8 секунд. Это уменьшает нагрузку на временно недоступный сервис. Случайный разброс задержки предотвращает ситуацию, когда множество задач повторяются одновременно.
Что не стоит повторять
ошибки валидации входных данных;
ошибки программирования и неверную конфигурацию;
операции с необратимым побочным эффектом без идемпотентного ключа;
ошибки доступа, если они не вызваны временным сбоем инфраструктуры.
После исчерпания попыток
После последней неудачной попытки задачу нужно записать в логи, отправить уведомление и при необходимости направить в отдельную очередь неуспешных сообщений. Нельзя создавать бесконечные повторные попытки: они могут перегрузить систему и скрыть ошибку.
Как ответить на собеседовании
Для временных ошибок использую self.retry() или autoretry_for. Настраиваю ограниченное число попыток, увеличивающуюся задержку и случайный разброс времени. Повторяю только ожидаемые временные ошибки, а задачу проектирую идемпотентной, потому что одна операция может быть выполнена повторно.
Оцени свой прогресс