Sobes.tech
Back to questions
Middle — Middle+
59

Каким образом обеспечить доставку сообщения точно один раз, избегая дублирования?

Answer from AI

sobes.tech AI

Для обеспечения доставки сообщения ровно один раз (exactly-once delivery) необходимо сочетать несколько подходов, так как в распределённых системах это нетривиальная задача:

  • Идемпотентность обработчиков сообщений: обработка одного и того же сообщения несколько раз не должна менять конечный результат.
  • Уникальные идентификаторы сообщений: каждое сообщение имеет уникальный ID, который сохраняется в базе при обработке.
  • Хранение состояния обработки: при получении сообщения проверяется, было ли оно уже обработано (по ID). Если да — игнорируется.
  • Транзакционное подтверждение: запись результата обработки и отметка сообщения как обработанного должны быть атомарными.

Пример на Python с использованием базы данных для отслеживания обработанных сообщений:

import sqlite3

conn = sqlite3.connect('messages.db')
conn.execute('''CREATE TABLE IF NOT EXISTS processed_messages (msg_id TEXT PRIMARY KEY)''')


def process_message(msg_id, payload):
    cursor = conn.cursor()
    cursor.execute('SELECT 1 FROM processed_messages WHERE msg_id = ?', (msg_id,))
    if cursor.fetchone():
        print('Сообщение уже обработано, пропускаем')
        return

    # Обработка сообщения
    print(f'Обрабатываем сообщение: {payload}')

    # Сохраняем факт обработки
    cursor.execute('INSERT INTO processed_messages (msg_id) VALUES (?)', (msg_id,))
    conn.commit()

# Пример вызова
process_message('12345', 'Данные')
process_message('12345', 'Данные')  # будет пропущено

Таким образом, даже при повторной доставке сообщение обработается только один раз.