Transactional Outbox — это шаблон проектирования, используемый в распределённых системах для обеспечения гарантированной отправки сообщений, особенно при интеграции с брокерами сообщений. Этот шаблон помогает решить проблему атомарности между изменениями в базе данных и отправкой событий, гарантируя, что сообщение будет отправлено только после успешного выполнения транзакции в базе данных.

Схема работы:

  1. При выполнении бизнес-операции, например, при изменении данных в базе данных, создаётся запись в таблице outbox. Эта запись содержит сообщение, которое нужно отправить другим сервисам.
  2. Операция создания записи в таблице outbox происходит в одной транзакции с основной бизнес-операцией. Это гарантирует, что и изменение данных, и запись сообщения будут выполнены атомарно.
  3. После успешной фиксации транзакции фоновый процесс или отдельный компонент читает сообщения из таблицы outbox и отправляет их в брокер сообщений.
  4. После успешной отправки сообщения запись в таблице outbox помечается как обработанная и спустя какое-то время удаляется.

Преимущества:

  • Гарантированная доставка сообщений: сообщения фиксируются вместе с бизнес-операциями, что предотвращает ситуацию, когда данные в базе данных обновлены, а сообщение не отправлено.
  • Упрощение архитектуры: использование таблицы outbox вместо распределённых транзакций (2PC) значительно упрощает архитектуру и позволяет избежать сложных механизмов блокировки.

Недостатки:

  • Дополнительная задержка: отправка сообщений через фоновый процесс может вызвать небольшую задержку в доставке сообщений, по сравнению с немедленной отправкой.
  • Увеличение нагрузки на базу данных: таблица outbox требует дополнительного хранения и управления, что увеличивает нагрузку на базу данных, особенно при большом объёме сообщений.

Сначала необходимо создать таблицу outbox в вашей базе данных для хранения сообщений, ожидающих отправки в Kafka.

Возможная структура outbox таблицы

CREATE TABLE outbox (
    id BIGSERIAL PRIMARY KEY,
    topic VARCHAR(255) NOT NULL,
    payload TEXT NOT NULL,
    status VARCHAR(20) DEFAULT 'PENDING',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • id: Уникальный идентификатор записи.
  • topic: Название топика/очереди, в который должно быть отправлено событие.
  • payload: данные события.
  • status: Статус обработки (PENDING, SENT, FAILED).
  • created_at и updated_at: Временные метки для отслеживания создания и обновления записи.

Мета информация

Область:: 00 Архитектура ПО
Родитель:: Паттерн проектирования
Источник::
Создана:: 2024-11-15
Автор::

Дополнительные материалы

Дочерние заметки