🔥
Saga pattern в PHP-микросервисах: как приручить хаос распределённых транзакцийПредставьте: вы заказываете пиццу через приложение. В этот момент включается цепочка микросервисов: проверяется аккаунт, блокируются деньги, резервируется товар, создаётся заказ, уведомляется курьер, списываются бонусы. Всё идёт гладко… пока один из шагов не ломается. Что делать?
👉 Здесь на сцену выходит
Saga pattern — способ координации распределённых транзакций без глобального коммита. Он превращает «монолитный» ACID-подход в управляемую серию шагов, каждый из которых либо завершается успешно, либо компенсируется обратным действием.
⚖️ Откуда растут ногиВ распределённых системах невозможно одновременно держать:
🔸 Consistency (согласованность),
🔸 Availability (доступность),
🔸 Partition Tolerance (устойчивость к сетевым сбоям).
CAP-теорема заставляет выбирать. Микросервисы обычно выбирают доступность + устойчивость, жертвуя мгновенной консистентностью.
Saga — это про
eventual consistency и отказ от «всё или ничего» в пользу гибкой компенсации.
🧩 Основные принципы SagaЛокальные транзакции — каждая операция выполняется внутри своего сервиса и своей базы.
Компенсирующие действия — для каждого шага определяется обратное (отмена заказа, возврат средств, снятие резерва).
Pivot-операция — «точка невозврата», после которой процесс обязан завершиться (например, списание средств или отправка товара).
Идемпотентность — шаги должны безопасно повторяться (например, повторный возврат денег не должен удвоить баланс).
Наблюдаемость — все шаги саги должны логироваться и мониториться как единый процесс.
🕺 Хореография vs 🎼 ОркестрацияХореография (event-driven):Сервисы реагируют на события друг друга («создан заказ» → «оплата прошла» → «товар зарезервирован»).
Плюсы: нет центрального управляющего, меньше точек отказа, естественная асинхронность.
Минусы: сложно тестировать и дебажить, растут циклы и зависимости.
Оркестрация (central coordinator):Есть управляющий компонент, который пошагово запускает сервисы и следит за компенсацией.
Плюсы: прозрачность, контроль, простая трассировка.
Минусы: единая точка отказа, риск узкого места.
🛡️
Типовые проблемы и решенияLost update: несколько саг меняют один ресурс. Решение — семантические блокировки или оптимистические версии.
ABA-проблема: значение успело измениться A→B→A. Решение — векторные часы, версии.
Dirty read: один сервис читает «грязные» данные другого. Решение — откладывать коммиты или использовать операции как очередь.
Подвисшие саги: шаг завис или умер. Решение — таймауты + процесс восстановления.
🏗️
Что важно в продеЧётко определённые компенсации для каждого шага.
Хранение состояния саги (статус, завершённые шаги, таймстемпы).
Автовосстановление: незавершённые саги нужно уметь продолжать или компенсировать.
Мониторинг и алерты: метрики (
saga.started,
saga.completed,
saga.failed).
Property-based тесты:
либо все шаги завершены,
либо все выполненные шаги компенсированы.
❓А вы бы выбрали
хореографию событий (больше свободы, но сложнее отлаживать) или
центрального дирижёра (прозрачность и контроль, но SPOF)?
🔗
Читать статьюБиблиотека пхпшника