Какие кейсы релевантны для перехода на использование очереди
Что проверяют
Понимаете ли вы, какую проблему решает очередь и какую новую сложность она приносит. Следом обычно спрашивают, как вы гарантируете, что задача не потеряется и не выполнится дважды.
Как отвечать
Назовите признаки, при которых очередь оправдана:
- долгая работа внутри запроса: генерация отчёта, обработка видео, отправка писем. Обработчик кладёт задачу и сразу отвечает
202 Accepted, а воркер выполняет её в фоне; - нестабильный внешний сервис: платёжный шлюз или API партнёра отвечает медленно или падает. Очередь даёт повторные попытки с экспоненциальной задержкой, не блокируя пользователя;
- пиковая нагрузка: всплески сглаживаются, воркеры разбирают очередь со своей скоростью и масштабируются отдельно от веб-части;
- развязка сервисов: событие «заказ оплачен» нужно нескольким потребителям. Здесь подходит брокер с подписками или журнал вроде Kafka;
- упор в CPU: из-за GIL тяжёлые вычисления в процессе веб-сервера тормозят все запросы, их выносят в отдельные процессы воркеров.
Инструменты: Celery с RabbitMQ или Redis, более лёгкие RQ, Dramatiq, arq для asyncio, Kafka для потоков событий с хранением и повторным чтением. Внутри процесса есть queue.Queue и asyncio.Queue, но при падении процесса задачи из них пропадут.
Обязательно скажите о цене: доставка почти всегда «как минимум один раз», поэтому обработчик должен быть идемпотентным. В Celery по умолчанию задача подтверждается до выполнения, и если воркер упадёт посреди работы, она потеряется; acks_late=True это меняет, но требует идемпотентности. Если задачу нужно поставить вместе с записью в базу, используют паттерн transactional outbox.
Где спотыкаются
Предлагают очередь для любой медленной операции, хотя иногда хватит индекса, кеша или asyncio. Очередь добавляет брокер, мониторинг и отложенную согласованность.
Забывают про повторы. Задача списания денег без ключа идемпотентности при повторной доставке спишет дважды.
Путают Kafka с очередью задач: в классической модели консьюмер-групп подтверждается смещение в партиции, а не отдельное сообщение, и отложенных повторов из коробки нет.