Друзья, привет!
Сегодня немного теории 🤓
Если вам в работе придётся сталкиваться с необходимостью гарантировано доставлять сообщения до какого-либо сервиса, то вам необходимо будет реализовать архитектурный паттерн Transactional Outbox (или просто Outbox).
Как работает паттерн?
Предположим, что есть два микросервиса: Сервис А и Сервис В.
Задача состоит в том, чтобы после получения сообщения в Сервис А, гарантировано передать данные из него в Сервис В.
Без использования какого-либо механизма обеспечения надежности этот процесс мог бы выглядеть следующим образом:
1. Сервис А обрабатывает запрос клиента.
2. После успешной обработки сообщения Сервис А отправляет сообщение в Сервис В через брокер (например, Kafka).
Но тут возникает проблема: если при передаче сообщения произойдет сбой (сеть упадет, очередь окажется перегруженной), мы можем потерять данные.
Сообщение будет обработано сервисом А, но до сервиса В не дойдет.
Чтобы избежать этой проблемы, используется паттерн Transactional Outbox.
В рамках этого подхода сообщение сначала сохраняется локально в базе данных, вместе с основным изменением состояния системы, что гарантирует атомарность сохранения данных, а затем в отдельном процессе отправляются во внешний сервис.
Примерный порядок действий выглядит так:
1⃣ Сервис А получает запрос.
2⃣ Затем внутри транзакции:
🔘Сохраняется информация о запросе
🔘Создается запись в таблице outbox с информацией о сообщении, которое должно быть доставлено
🔘Транзакция фиксируется
3⃣ Асинхронная задача (шедулер в сервисе А) берет записи из таблицы outbox и пытается отправить их в сервис В:
🔘Если доставка прошла успешно, то в БД данной записи проставляется атрибут (например status), свидетельствующий об ее успешной отправке в сервис В, или запись удаляется из таблицы outbox
🔘Если происходит ошибка при доставке, асинхронная задача продолжает попытки до тех пор, пока доставка не завершится удачно
4⃣ Сервис В читает сообщения из брокера.
Таким образом, таблица outbox действует как временный буфер для хранения сообщений, гарантирующий, что данные будут переданы независимо от внешних факторов.
Сегодня немного теории 🤓
Если вам в работе придётся сталкиваться с необходимостью гарантировано доставлять сообщения до какого-либо сервиса, то вам необходимо будет реализовать архитектурный паттерн Transactional Outbox (или просто Outbox).
Как работает паттерн?
Предположим, что есть два микросервиса: Сервис А и Сервис В.
Задача состоит в том, чтобы после получения сообщения в Сервис А, гарантировано передать данные из него в Сервис В.
Без использования какого-либо механизма обеспечения надежности этот процесс мог бы выглядеть следующим образом:
1. Сервис А обрабатывает запрос клиента.
2. После успешной обработки сообщения Сервис А отправляет сообщение в Сервис В через брокер (например, Kafka).
Но тут возникает проблема: если при передаче сообщения произойдет сбой (сеть упадет, очередь окажется перегруженной), мы можем потерять данные.
Сообщение будет обработано сервисом А, но до сервиса В не дойдет.
Чтобы избежать этой проблемы, используется паттерн Transactional Outbox.
В рамках этого подхода сообщение сначала сохраняется локально в базе данных, вместе с основным изменением состояния системы, что гарантирует атомарность сохранения данных, а затем в отдельном процессе отправляются во внешний сервис.
Примерный порядок действий выглядит так:
1⃣ Сервис А получает запрос.
2⃣ Затем внутри транзакции:
🔘Сохраняется информация о запросе
🔘Создается запись в таблице outbox с информацией о сообщении, которое должно быть доставлено
🔘Транзакция фиксируется
3⃣ Асинхронная задача (шедулер в сервисе А) берет записи из таблицы outbox и пытается отправить их в сервис В:
🔘Если доставка прошла успешно, то в БД данной записи проставляется атрибут (например status), свидетельствующий об ее успешной отправке в сервис В, или запись удаляется из таблицы outbox
🔘Если происходит ошибка при доставке, асинхронная задача продолжает попытки до тех пор, пока доставка не завершится удачно
4⃣ Сервис В читает сообщения из брокера.
Таким образом, таблица outbox действует как временный буфер для хранения сообщений, гарантирующий, что данные будут переданы независимо от внешних факторов.