Saga pattern
Тема дорожной карты · Software Architecture
Сага-паттерн (Saga pattern) представляет собой метод координации распределённых транзакций между сервисами без использования двухфазного подтверждения (2-phase commit). Этот паттерн имеет важное значение в микросервисной архитектуре, поскольку распределённые транзакции между гетерогенными хранилищами обычно невозможны. Сага-паттерн позволяет выполнять сложные бизнес-процессы, которые охватывают несколько сервисов, обеспечивая целостность данных и устойчивость системы.
Как это работает
Сага-паттерн предлагает два основных подхода: choreography и orchestration. В choreography каждый сервис публикует события и слушает события других сервисов, что позволяет избежать необходимости центрального координатора. Эта модель обладает высокой степенью декомпозиции и автономии, но при этом усложняет отладку и понимание общего потока событий. В orchestration используется центральный saga-manager (например, Camunda, Temporal), который явно управляет каждым шагом и обрабатывает компенсационные действия. Этот подход обеспечивает более централизованное управление ошибками и более прозрачный поток выполнения, но требует тесной интеграции с saga-managerом.
Когда применять
Сага-паттерн особенно полезен, когда бизнес-процесс охватывает несколько сервисов и частичное завершение может оставить систему в несогласованном состоянии. Например, при создании заказа требуется зарезервировать инвентарь, списать платёж и создать отправку. Если любой из этих шагов провалится, остальные шаги должны быть отменены через компенсационные действия. Сага-паттерн не следует применять для транзакций, которые могут быть полностью выполнены внутри одного сервиса с использованием ACID-свойств базы данных.
Типичные ошибки
- Использование choreography по умолчанию — хотя choreography может быть привлекательной для теоретического подхода, на практике она усложняет отладку и понимание потока событий.
- Проектирование компенсационных действий как afterthought — часто разработчики фокусируются на проектировании основного пути выполнения (happy path), а затем пытаются добавить компенсационные действия. Это может привести к сложностям и невозможности реализации компенсации.
- Недостаток timeout или только timeout — распределённые шаги могут зависать, что требует наличия как timeout, так и соответствующих компенсационных действий для обработки ситуации timeout.