Повышение надежности сообщений с помощью шаблона транзакционных исходящих сообщений

Вы устали решать проблемы доставки сообщений в распределенных системах? Не смотрите дальше! В этой статье блога мы углубимся в шаблон транзакционных исходящих сообщений — невероятно мощный метод повышения надежности сообщений и обеспечения бесперебойной связи между микросервисами.

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

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

Теперь давайте рассмотрим некоторые популярные методы реализации шаблона транзакционных исходящих сообщений:

  1. Триггер базы данных:
    Каждый раз, когда внутри службы происходит соответствующая транзакционная операция, триггер базы данных может использоваться для сбора необходимой информации и вставки ее в таблицу исходящих сообщений. Этот метод гарантирует, что сообщения создаются автоматически без явного кодирования.

    CREATE TRIGGER outbox_trigger
    AFTER INSERT ON orders
    FOR EACH ROW
    BEGIN
     INSERT INTO outbox (message) VALUES (NEW.message);
    END;
  2. Журнал транзакций.
    Другой подход — использовать журнал транзакций вашей базы данных. Анализируя журнал, вы можете извлечь необходимые изменения и сгенерировать соответствующие сообщения, которые будут сохранены в таблице исходящих сообщений.

    TransactionLog log = getTransactionLog();
    List<TransactionEvent> events = log.getUnprocessedEvents();
    
    for (TransactionEvent event : events) {
     Message message = convertToMessage(event);
     outboxRepository.save(message);
    }
  3. Источник событий.
    Если ваша система использует источник событий, шаблон Transactional Outbox можно легко интегрировать. События, генерируемые во время обработки команд, автоматически сохраняются в таблице исходящих сообщений в рамках той же транзакции.

    public void handleOrderPlaced(OrderPlacedEvent event) {
     // Process the event and update the state of the order
     // ...
    
     Message message = createMessage(event);
     outboxRepository.save(message);
    }
  4. Асинхронная задача.
    В сценариях, где немедленная обработка сообщений не требуется, вы можете ввести асинхронную задачу, которая периодически сканирует базу данных на наличие новых записей в таблице исходящих сообщений и отправляет сообщения брокеру.

  5. Асинхронная задача.
    В сценариях, где немедленная обработка сообщений не требуется, вы можете ввести асинхронную задачу, которая периодически сканирует базу данных на наличие новых записей в таблице исходящих сообщений и отправляет сообщения брокеру.

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

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

    Асинхронная задача. р>

    def process_outbox():
     while True:
       messages = outbox_repository.get_pending_messages()
    
       for message in messages:
         message_broker.send(message)
         outbox_repository.mark_as_sent(message)
    
       sleep(1)  # Delay between processing loop iterations

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

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

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

Так зачем ждать? Начните внедрять шаблон транзакционных исходящих сообщений в свои микросервисы уже сегодня и ощутите преимущества на собственном опыте!