Ответ
Гарантия доставки — это соглашение о надёжности, которое система обязуется выполнить при передаче сообщения от отправителя (producer) к получателю (consumer). Существует три основных уровня:
-
At-most-once (не более одного раза)
- Сообщение доставляется 0 или 1 раз. Это самый быстрый, но наименее надёжный уровень. Сообщения могут быть утеряны при сбое сети или падении потребителя до подтверждения.
- Применение: Некритические данные, где потеря сообщения допустима (например, сбор метрик, логов).
-
At-least-once (как минимум один раз)
- Гарантирует, что сообщение будет доставлено, но допускает дубликаты. Потребитель должен подтвердить (acknowledge) получение сообщения. Если подтверждение не приходит, брокер отправляет сообщение повторно.
- Применение: Самый распространённый сценарий, где важна доставка, а потребитель спроектирован идемпотентным (повторная обработка дубля не вызывает проблем).
-
Exactly-once (ровно один раз)
- Самый строгий уровень: каждое сообщение доставляется и обрабатывается ровно один раз. Требует сложных механизмов, таких как транзакции или дедупликация на стороне потребителя и брокера.
- Применение: Критически важные системы, где дубликаты недопустимы (например, финансовые транзакции).
Пример реализации At-least-once в RabbitMQ:
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# 1. Объявляем очередь как 'durable', чтобы она пережила перезапуск брокера.
channel.queue_declare(queue='task_queue', durable=True)
# 2. Включаем подтверждения от брокера (Publisher Confirms).
channel.confirm_delivery()
# 3. Отправляем сообщение с 'delivery_mode=Persistent',
# чтобы оно сохранялось на диск.
channel.basic_publish(
exchange='',
routing_key='task_queue',
body='Task message',
properties=pika.BasicProperties(
delivery_mode=pika.DeliveryMode.Persistent
)
)
print(" [x] Sent 'Task message'")
connection.close()
На стороне потребителя для этой схемы необходимо отправлять подтверждения (channel.basic_ack()
) после успешной обработки сообщения.