Расскажите про паттерн Saga. Какие проблемы он решает и какие существуют подходы к его реализации?

Ответ

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

Проблема: В микросервисах каждый сервис обычно владеет своей базой данных. Выполнение бизнес-операции, затрагивающей несколько сервисов (например, "заказ товара" = Списание денег + Резервирование на складе + Создание доставки), не может быть обернуто в одну транзакцию. Если один из шагов падает, система остается в несогласованном состоянии.

Решение Saga: Сага разбивает глобальную транзакцию на последовательность локальных транзакций в каждом сервисе. Если какой-либо шаг не удается, сага выполняет компенсирующие транзакции в обратном порядке, чтобы отменить уже выполненные шаги.

Существует два основных подхода к реализации саги:

1. Хореография (Choreography)

Сервисы общаются друг с другом напрямую через асинхронные события (events). Нет центрального координатора.

  • Как работает:

    1. Сервис Заказов создает заказ и публикует событие OrderCreated.
    2. Сервис Платежей слушает это событие, списывает деньги и публикует PaymentProcessed.
    3. Сервис Склада слушает PaymentProcessed, резервирует товар и публикует StockReserved.

  • Откат: Если сервис Склада не может зарезервировать товар, он публикует событие StockReservationFailed. Сервис Платежей слушает его и выполняет компенсирующее действие (возврат денег), публикуя PaymentRefunded. Сервис Заказов отменяет заказ.


  • Плюсы:

    • Простота и слабая связанность (loose coupling).
    • Нет единой точки отказа.
  • Минусы:

    • Сложно отслеживать общую картину процесса (циклические зависимости, какой сервис кого слушает).
    • Отладка может превратиться в ад.

2. Оркестрация (Orchestration)

Существует отдельный сервис-оркестратор, который управляет всем процессом, отправляя команды каждому участнику саги.

  • Как работает:

    1. Клиент обращается к Оркестратору с просьбой создать заказ.
    2. Оркестратор отправляет команду ProcessPayment сервису Платежей.
    3. После получения подтверждения, он отправляет команду ReserveStock сервису Склада.

  • Откат: Если какой-либо сервис сообщает об ошибке, Оркестратор знает, какие шаги уже были выполнены, и отправляет компенсирующие команды (RefundPayment, ReleaseStock) в обратном порядке.


  • Плюсы:

    • Централизованная логика, легко понять и отладить весь процесс.
    • Проще управлять сложными сценариями.
  • Минусы:

    • Появляется единая точка отказа (оркестратор).
    • Более сильная связанность сервисов с оркестратором.