Зачем нужен Celery в Python
Что проверяют
Понимаете ли вы, зачем выносить работу из веб-процесса, и знаете ли подводные камни фоновых задач: повторы, идемпотентность, потерянные задачи.
Как отвечать
Celery это очередь задач: код кладёт задачу в брокер (обычно Redis или RabbitMQ), отдельный процесс-исполнитель забирает и выполняет её вне цикла обработки запроса.
Зачем это нужно:
- длинные операции: отправка писем, генерация отчётов и PDF, обработка изображений, вызовы внешних API. Держать веб-процесс занятым на это нельзя, пользователь ждёт ответ;
- расписание: периодические задачи через Celery Beat вместо системного cron;
- всплески нагрузки: очередь сглаживает пик, исполнители разбирают её в своём темпе;
- изоляция сбоев: упавшая задача повторяется, а не роняет запрос пользователя.
@app.task(bind=True, max_retries=3, autoretry_for=(RequestException,), retry_backoff=True)
def send_digest(self, user_id: int) -> None:
...Что важно назвать помимо определения: задачи обязаны быть идемпотентными, потому что доставка «хотя бы один раз» и повтор случается штатно. Аргументы передаются сериализуемые, поэтому передают идентификатор, а не объект модели: пока задача ждёт в очереди, запись успевает измениться.
Где спотыкаются
Передают в задачу объект целиком и получают устаревшие данные или ошибку сериализации.
Не настраивают повторы и таймауты, и одна зависшая задача занимает исполнителя навсегда.
Не думают об идемпотентности: повторная доставка отправляет письмо дважды.
Не знают об альтернативах и тащат Celery в маленький проект, где хватило бы arq, dramatiq или фоновых задач самого фреймворка.