Ответ
Гарантия доставки — это свойство системы обмена сообщениями, при котором брокер (например, RabbitMQ, Apache Kafka) обеспечивает, что отправленное сообщение будет обработано потребителем как минимум один раз, даже в случае сбоев на стороне брокера, отправителя или получателя.
С точки зрения тестирования, важно понимать и проверять эти механизмы:
Ключевые механизмы гарантии доставки:
- Подтверждение (Acknowledgement): Потребитель должен явно подтвердить (
ack) успешную обработку сообщения. Без подтверждения брокер считает сообщение не доставленным и может перенаправить его другому потребителю. - Сохранение на диск (Persistence): Сообщения и метаданные очередей сохраняются на диск, чтобы пережить перезапуск брокера.
- Репликация и кворумы: В кластерных конфигурациях (Kafka, RabbitMQ Quorum Queues) сообщения реплицируются на несколько узлов для отказоустойчивости.
Пример тестового сценария для RabbitMQ:
import pika
# Подключение к брокеру
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
# Объявление устойчивой (durable) очереди
channel.queue_declare(queue='test_payment_queue', durable=True)
# Публикация сообщения в persistent-режиме
channel.basic_publish(
exchange='',
routing_key='test_payment_queue',
body='Test payment data',
properties=pika.BasicProperties(
delivery_mode=2, # Делает сообщение persistent
)
)
print(" [x] Sent 'Test payment data'")
# --- Сторона потребителя (тестового сервиса) ---
def callback(ch, method, properties, body):
print(f" [x] Received {body}")
# Имитация обработки и проверки данных
if process_payment(body):
# Явное подтверждение ТОЛЬКО после успешной обработки
ch.basic_ack(delivery_tag=method.delivery_tag)
else:
# Отказ от подтверждения. Сообщение будет повторно доставлено или попадет в DLQ
ch.basic_nack(delivery_tag=method.delivery_tag)
# Подписка с отключенным auto_ack
channel.basic_consume(queue='test_payment_queue', on_message_callback=callback, auto_ack=False)
channel.start_consuming()
При тестировании мы специально эмулируем сбои (убиваем процесс потребителя) и проверяем, что сообщения не теряются и обрабатываются повторно, а также отслеживаем появление сообщений в Dead Letter Queue при многократных неудачах.