> Что такое саги в микросервисах (JavaScript)
Уровень: junior · Роль: backend · Язык: JavaScript · Категория: Технические вопросы
Компании: TrendTech
Стек: Node.js, JavaScript
> Пример ответа
Короткий ответ
Саги в микросервисах - это паттерн для управления распределёнными транзакциями. Вместо ACID используется последовательность локальных транзакций с компенсирующими действиями при сбоях. Каждый сервис выполняет свою операцию и публикует событие, запускающее следующий шаг. Если что-то идёт не так, запускаются компенсирующие транзакции для отката уже выполненных шагов.
Подробное объяснение
В монолитной архитектуре транзакции обычно обрабатываются с помощью ACID - атомарность, согласованность, изоляция, долговечность. В микросервисах каждый сервис имеет свою базу данных, поэтому распределённые транзакции через двухфазный коммит (2PC) становятся сложными и медленными. Саги решают эту проблему, разбивая транзакцию на несколько локальных шагов.
Существует два подхода к реализации саг:
-
Хореография (choreography) - каждый сервис после выполнения своей операции публикует событие, на которое подписываются другие сервисы. Нет центрального координатора. Пример: сервис заказов создаёт заказ → публикует событие
OrderCreated→ сервис оплаты обрабатывает оплату → публикуетPaymentProcessed→ сервис доставки начинает доставку. -
Оркестрация (orchestration) - есть центральный оркестратор, который управляет последовательностью шагов и вызывает каждый сервис. Оркестратор хранит состояние саги и при ошибке запускает компенсирующие действия.
Компенсирующие транзакции - это действия, которые отменяют эффект уже выполненного шага. Например, если оплата прошла, а доставка не удалась, нужно вернуть деньги. Компенсация должна быть идемпотентной и надёжной.
На практике
В Node.js саги часто реализуются с помощью message broker (например, RabbitMQ, Kafka) или библиотек вроде sagas-js, brigade или temporal. Для хореографии используют event-driven подход: сервисы общаются через события. Для оркестрации - отдельный микросервис-оркестратор, который вызывает API других сервисов.
Важно учитывать:
- Саги не гарантируют изоляцию - возможны промежуточные состояния, видимые другим сервисам.
- Нужна идемпотентность обработчиков событий и компенсирующих действий.
- События должны быть durable (сохраняться в очередь) и обрабатываться в правильном порядке.
- Мониторинг и логирование критичны для отладки сбоев в сагах.
Пример кода
Пример простой хореографии саги для заказа:
JAVASCRIPT// Сервис заказовclass OrderService {async createOrder(orderData) {const order = await db.orders.create(orderData);await eventBus.publish('order.created', { orderId: order.id });return order;}async compensateOrder(orderId) {await db.orders.update(orderId, { status: 'cancelled' });await eventBus.publish('order.cancelled', { orderId });}}// Сервис оплатыclass PaymentService {async handleOrderCreated(event) {try {const payment = await processPayment(event.orderId);await eventBus.publish('payment.processed', { orderId: event.orderId });} catch (error) {await eventBus.publish('payment.failed', { orderId: event.orderId });}}async compensatePayment(orderId) {await refundPayment(orderId);await eventBus.publish('payment.refunded', { orderId });}}// Сервис доставкиclass DeliveryService {async handlePaymentProcessed(event) {try {await scheduleDelivery(event.orderId);await eventBus.publish('delivery.scheduled', { orderId: event.orderId });} catch (error) {await eventBus.publish('delivery.failed', { orderId: event.orderId });}}}// Компенсация при сбое доставкиeventBus.on('delivery.failed', async (event) => {await paymentService.compensatePayment(event.orderId);await orderService.compensateOrder(event.orderId);});
Как отвечать на собеседовании
Начни с краткого определения саги как паттерна для распределённых транзакций. Объясни проблему, которую решают саги - невозможность ACID в микросервисах. Упомяни два подхода: хореография и оркестрация. Приведи простой пример из e-commerce: заказ → оплата → доставка. Скажи, что в Node.js часто используют message broker и event-driven архитектуру. Не углубляйся в детали реализации, если не спрашивают.
Что проверяет интервьюер
- Понимание ограничений распределённых систем и почему ACID не работает в микросервисах.
- Знание базовых паттернов для управления транзакциями.
- Умение различать хореографию и оркестрацию.
- Понимание компенсирующих транзакций и идемпотентности.
- Осознание trade-off: саги не дают изоляции, возможны промежуточные состояния.
Типичные ошибки
- Путать саги с двухфазным коммитом (2PC) - это разные подходы.
- Думать, что саги гарантируют ACID - они обеспечивают только eventual consistency.
- Игнорировать идемпотентность - повторные события могут вызвать дублирование операций.
- Не предусматривать компенсирующие действия для каждого шага.
- Считать, что саги подходят для всех случаев - иногда достаточно простой очереди с retry.
> Похожие задачи по JavaScript
Какая библиотека для IoC контейнера использовалась
Насколько жестко проект был разделен на ограниченные контексты и агрегаты в DDD
Что такое двухфазная фиксация в микросервисах
Какие приоритеты при выборе вакансии
> Похожие задачи по backend
В чем отличие ноды, пода и сервиса в Kubernetes
Как организовать транзакционность в микросервисной архитектуре при работе с разными базами данных
Что такое двухфазная фиксация в микросервисах
Что дает NodePort в Kubernetes
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью