Вопрос проверяет понимание, какие уровни надежности нужны со стороны брокера, продюсера и консюмера, чтобы не терять сообщения при сбоях.
Короткий ответ (3–6 предложений)
Чтобы сообщение не потерялось при падении воркера, используют ручные подтверждения (ack) и подтверждают сообщение только после успешной обработки. Чтобы не потерять сообщение при падении брокера, делают очередь “устойчивой” (durable) и публикуют сообщения как persistent. Для надежной публикации применяют publisher confirms, чтобы продюсер знал, что брокер принял сообщение. Для отказоустойчивости очереди используют репликацию (например, quorum queues). Для проблемных сообщений добавляют DLQ и retry-механизмы.
Надежность “сообщение не потеряется” достигается комбинацией механизмов на разных этапах: публикация, хранение, доставка, обработка.
Ручные подтверждения (manual ack)
сообщение считается обработанным только после basic_ack.
при падении до ack оно вернется в очередь и будет переотправлено.
prefetch (QoS)
ограничивает количество сообщений, одновременно выданных воркеру.
уменьшает объем “недообработанного” при падении.
Устойчивая очередь (durable queue)
очередь переживает рестарт брокера (в терминах метаданных).
Персистентные сообщения (persistent messages)
сообщение помечается для записи на диск.
важно: это не абсолютная гарантия без правильной конфигурации и подтверждений от брокера.
Репликация очереди
quorum queue (репликация через Raft) обычно дает более предсказуемую устойчивость при падениях узлов кластера.
Publisher confirms
продюсер получает подтверждение от брокера, что публикация принята.
при отсутствии confirm продюсер может повторить отправку (отсюда снова нужна идемпотентность).
Обработка возвратов (mandatory + return)
если сообщение не может быть маршрутизировано, продюсер узнает об этом и не “теряет” его молча.
Dead Letter Exchange / Dead Letter Queue (DLX/DLQ)
сообщения, которые нельзя обработать, уходят в отдельную очередь для анализа/ретраев.
Retry-стратегия
повторные попытки через отдельные очереди с TTL (отложенная повторная доставка), либо через delayed message plugin (если используется).
channel.confirm_delivery() # включить publisher confirms
ok = channel.basic_publish(
exchange="",
routing_key="tasks",
body=b"...",
properties=pika.BasicProperties(delivery_mode=2), # persistent
)
if not ok:
# повторить публикацию / записать в outbox
handle_publish_failure()
Вывод
Чтобы “не терять” сообщения, обычно комбинируют: manual ack у консюмера, durable + persistent у брокера, publisher confirms у продюсера и DLQ/retry для нештатных кейсов.