← Назад ко всем вопросам

Почему в брокерах часто ‘at-least-once’ и как жить с дублями?

1️⃣ Как кратко ответить

В брокерах сообщений часто используется модель доставки 'at-least-once', чтобы гарантировать, что каждое сообщение будет доставлено хотя бы один раз, даже в случае сбоев. Это может привести к дублированию сообщений, с которыми можно справиться с помощью уникальных идентификаторов сообщений и идемпотентных операций на стороне потребителя.

2️⃣ Подробное объяснение темы

В системах обмена сообщениями, таких как брокеры сообщений (например, Apache Kafka, RabbitMQ), модель доставки 'at-least-once' означает, что каждое сообщение будет доставлено получателю как минимум один раз. Это достигается за счет повторной отправки сообщений в случае сбоев, таких как временные сетевые проблемы или сбои потребителей. Однако это может привести к дублированию сообщений, поскольку одно и то же сообщение может быть доставлено несколько раз.

Зачем нужна модель 'at-least-once'?

  • Надежность: В критически важных системах, где потеря сообщений недопустима, 'at-least-once' обеспечивает надежность доставки. Это особенно важно в финансовых приложениях, системах мониторинга и других областях, где каждое сообщение имеет значение.
  • Сбойоустойчивость: В случае временных сбоев в сети или на стороне потребителя, повторная отправка сообщений гарантирует, что они не будут потеряны.

Как работает 'at-least-once'?

  1. Отправка сообщения: Производитель отправляет сообщение в брокер.
  2. Подтверждение доставки: Брокер сохраняет сообщение и отправляет подтверждение производителю.
  3. Доставка потребителю: Брокер отправляет сообщение потребителю.
  4. Подтверждение получения: Потребитель обрабатывает сообщение и отправляет подтверждение брокеру.
  5. Повторная отправка при сбое: Если подтверждение от потребителя не получено, брокер повторно отправляет сообщение.

Как жить с дублями?

Чтобы справиться с дублированием сообщений, можно использовать следующие подходы:

  • Уникальные идентификаторы сообщений: Каждое сообщение должно иметь уникальный идентификатор. Потребитель может хранить список обработанных идентификаторов и игнорировать дублирующиеся сообщения.

    processed_ids = set()
    ​
    def process_message(message):
        if message.id in processed_ids:
            return  # Сообщение уже обработано
        # Обработка сообщения
        processed_ids.add(message.id)
    
  • Идемпотентные операции: Операции, выполняемые потребителем, должны быть идемпотентными, то есть их повторное выполнение не должно изменять результат. Например, если операция заключается в обновлении записи в базе данных, она должна быть спроектирована так, чтобы повторное выполнение не изменяло состояние системы.

  • Использование транзакций: В некоторых системах можно использовать транзакции для обеспечения атомарности операций. Это позволяет гарантировать, что операция будет выполнена только один раз, даже если сообщение будет получено несколько раз.

Применение на практике

В реальных системах выбор модели доставки зависит от требований к надежности и допустимости дублирования. 'At-least-once' подходит для систем, где потеря сообщений недопустима, но дублирование может быть обработано на уровне приложения. Важно проектировать системы с учетом возможных дублирований и использовать подходящие методы для их обработки.

Тема: Очереди и брокеры сообщений
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки