Ответ
RabbitMQ предоставляет несколько уровней гарантий, которые настраиваются в зависимости от требований к надежности системы. Основные из них:
-
At-least-once delivery (Доставка как минимум один раз) Это достигается через механизм подтверждений (acknowledgements,
ack
). Потребитель (consumer) после успешной обработки сообщения отправляет брокеруack
. Если брокер не получилack
(например, из-за сбоя потребителя), он вернет сообщение в очередь для обработки другим потребителем. Это предотвращает потерю сообщений, но может привести к дублированию обработки. -
Сохранение сообщений (Durability) Для защиты от потери данных при перезапуске или сбое брокера используются:
- Durable queues (надежные очереди): Такие очереди сохраняются на диск и восстанавливаются после перезапуска.
- Persistent messages (постоянные сообщения): Сообщения, помеченные как
persistent
, также сохраняются на диск.
-
Порядок сообщений (Ordering) RabbitMQ гарантирует порядок доставки сообщений FIFO (First-In-First-Out) в рамках одной очереди и одного потребителя. Если у очереди несколько потребителей, гарантия порядка между ними не предоставляется.
Пример с ручным подтверждением (ack) на Python (pika):
import pika
def callback(ch, method, properties, body):
print(f" [x] Received {body.decode()}")
# ... здесь логика обработки сообщения ...
print(" [x] Done")
# Отправляем подтверждение брокеру
ch.basic_ack(delivery_tag=method.delivery_tag)
# ... код подключения ...
channel.basic_consume(
queue='task_queue',
on_message_callback=callback,
auto_ack=False # Отключаем автоматическое подтверждение
)
channel.start_consuming()
Важные оговорки:
- Нет гарантии "exactly-once" из коробки: Для ее реализации требуется идемпотентность на стороне потребителя.
- Порядок может нарушаться: При использовании нескольких потребителей или при переотправке неподтвержденных сообщений (
nack
).