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

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

2.4 Senior🔥 91 комментариев
#Брокеры сообщений и очереди

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Модели гарантии доставки сообщений

В распределенных системах и системах обмена сообщениями (message queue, message broker) используются различные модели гарантии доставки. Выбор правильной модели зависит от критичности данных и требований приложения.

Три основные модели гарантии доставки

At-Most-Once (максимум один раз)

При модели At-Most-Once сообщение может быть доставлено 0 или 1 раз. Это означает, что сообщение может быть потеряно, но не будет обработано дважды.

// Пример: Простая отправка без подтверждения
producer.send({
  topic: 'events',
  messages: [{ value: 'some-data' }]
  // Нет ожидания подтверждения
});

Характеристики:

  • Быстрая доставка
  • Возможна потеря данных
  • Нет дублирования
  • Примеры: UDP, некритичные логи

Использование:

  • Метрики и статистика
  • Некритичные уведомления
  • Аналитика

At-Least-Once (минимум один раз)

При модели At-Least-Once сообщение гарантированно доставляется минимум один раз, но может быть доставлено несколько раз.

// Пример: Kafka с подтверждением
const producer = kafka.producer({
  idempotent: true,  // Поддержка идемпотентности
  maxInFlightRequests: 5
});

await producer.send({
  topic: 'events',
  messages: [{ 
    key: 'user-123',
    value: JSON.stringify({ action: 'purchase' })
  }]
});

// Потребитель должен быть идемпотентным
consumer.on('message', async (message) => {
  // Обрабатываем, даже если придет дважды
  await processMessage(message);
  consumer.commitOffset(message);
});

Характеристики:

  • Гарантия доставки
  • Возможна обработка дважды (или больше)
  • Требует идемпотентности потребителя
  • Примеры: Kafka, RabbitMQ с ACK

Использование:

  • Финансовые операции (где можно отслеживать дубликаты)
  • Критичные уведомления
  • Аналитика с требованиями к точности

Exactly-Once (ровно один раз)

При модели Exactly-Once сообщение доставляется ровно один раз - не теряется и не дублируется.

// Пример: Kafka с транзакциями
const producer = kafka.producer({
  idempotent: true,
  transactionalId: 'producer-id-1',
  transactionTimeout: 30000
});

await producer.transaction(async (trx) => {
  await trx.send({
    topic: 'payments',
    messages: [{ 
      value: JSON.stringify({ 
        orderId: '123',
        amount: 100 
      })
    }]
  });
  
  await updateDatabase();
});

// На стороне потребителя
const consumer = kafka.consumer({
  groupId: 'payment-processor'
});

consumer.on('message', async (message) => {
  const session = await db.beginTransaction();
  try {
    await processPayment(message, session);
    await session.commit();
    await consumer.commitOffset(message);
  } catch (error) {
    await session.rollback();
  }
});

Характеристики:

  • Нет потерь, нет дублирования
  • Использует транзакции
  • Более сложно и медленнее
  • Примеры: Kafka с транзакциями

Использование:

  • Финансовые транзакции
  • Критичные операции с состоянием
  • Системы с требованиями к консистентности

Таблица сравнения

МодельПотеряДублированиеПроизводительностьСложность
At-Most-OnceВозможнаНетВысокаяНизкая
At-Least-OnceНетВозможноСредняяСредняя
Exactly-OnceНетНетНизкаяВысокая

Практические рекомендации

Для системы заказов:

const order = {
  id: 'order-123',
  customerId: 'user-456',
  items: [...]
};

Идемпотентная обработка (At-Least-Once):

const processedMessages = new Set();

async function handleMessage(message) {
  if (processedMessages.has(message.id)) {
    return;
  }
  
  await processPayment(message);
  processedMessages.add(message.id);
}

Выбор для проекта:

  • Логирование, метрики: At-Most-Once
  • Уведомления, аналитика: At-Least-Once
  • Платежи, критичные данные: Exactly-Once

Правильный выбор модели гарантии доставки критичен для надежности системы. Для большинства коммерческих приложений рекомендуется At-Least-Once с идемпотентной обработкой, так как это обеспечивает хороший баланс между надежностью и производительностью.