Есть ли причины с точки зрения стабильности и сохранности данных для использования очереди
Что проверяют
Понимаете ли вы, что очередь сама по себе данные не спасает, а даёт механизмы, которые нужно правильно включить. Следом обычно спрашивают, что будет, если воркер упадёт посреди обработки, и как не выполнить задачу дважды.
Как отвечать
Причины в пользу очереди есть, назовите их конкретно:
- буфер нагрузки: пики складываются в очередь, а не роняют сервис, воркеры разбирают её в своём темпе;
- развязка по времени: если обработчик или внешний сервис недоступен, сообщения ждут, а не теряются вместе с HTTP-запросом;
- повторы: неудачную задачу можно вернуть в очередь с задержкой, а после нескольких попыток отправить в dead letter queue для разбора.
Теперь условия, без которых этого не будет:
- долговечность в брокере: в RabbitMQ очередь объявляют с
durable=True, сообщения публикуют persistent (delivery_mode=2) и включают publisher confirms. В Kafka нужныacks=all, репликация иmin.insync.replicas. Redis в роли брокера без AOF при падении может потерять последние данные; - подтверждение после обработки: сообщение подтверждают, только когда работа сделана. В Celery по умолчанию задача подтверждается перед выполнением, поэтому для надёжности включают
task_acks_late=Trueиtask_reject_on_worker_lost=True, а в Kafka коммитят offset после обработки; - идемпотентность: такая схема даёт доставку «хотя бы один раз», значит дубли будут. Обработчик должен их переживать: ключ идемпотентности, уникальный индекс, проверка статуса;
- transactional outbox: запись в базу и отправка в очередь не атомарны, поэтому событие сначала пишут в таблицу в той же транзакции, а отдельный процесс публикует его.
Где спотыкаются
Говорят «положили в очередь, значит не потеряется». Без durable-очереди, persistent-сообщений и позднего подтверждения данные пропадают при первом рестарте.
Обещают exactly-once. На практике это at-least-once плюс идемпотентный обработчик, и честнее так и сказать.
Забывают про ядовитые сообщения: задача, которая падает всегда, без лимита попыток и DLQ крутится бесконечно и мешает остальным.