Инженерия ПО

Микросервисы: паттерны

Цели урока

  • Знать каноничные паттерны микросервисов: Circuit Breaker, Saga, API Gateway, BFF, Service Mesh
  • Понимать, когда нужен Saga вместо распределённой транзакции с 2PC
  • Применять Circuit Breaker для защиты от каскадных отказов между сервисами
  • Различать orchestration и choreography для Saga и видеть trade-off
  • Использовать Outbox Pattern для гарантии 'один раз' при публикации событий

Предварительные знания

  • Понимание чем микросервис отличается от монолита (предыдущий урок se-21)
  • Знание REST/gRPC и брокеров сообщений (Kafka, RabbitMQ) на базовом уровне
  • Опыт работы с любым облаком или контейнерами

Netflix 2012 год: переход с монолита на микросервисы. Сегодня 700+ микросервисов, 2+ миллиарда запросов в день через API Gateway, Chaos Monkey случайно убивает сервисы в production и система продолжает работать. Это стало возможным благодаря паттернам: Circuit Breaker предотвращает каскадные отказы, Saga обеспечивает distributed transactions, Service Mesh делает mTLS и observability прозрачными.

  • **Netflix Hystrix**: первая широко используемая реализация Circuit Breaker в микросервисах, разработана для предотвращения каскадных отказов в 700+ сервисной экосистеме
  • **Uber Eats Saga**: оформление заказа проходит через Payment, Restaurant, Driver services с compensating actions при отказе любого звена - Saga orchestration
  • **Lyft Envoy**: разработали sidecar proxy для своей микросервисной архитектуры, который стал основой Istio Service Mesh - используется в тысячах production систем

API Gateway

API Gateway - единственная точка входа для клиентов в экосистему микросервисов. Принимает запросы от frontend/mobile, маршрутизирует к нужным сервисам, агрегирует ответы. Netflix API Gateway обрабатывает более 2 миллиардов запросов в день, агрегируя данные из 700+ микросервисов за один запрос клиента. Без Gateway клиент должен знать адреса всех сервисов и делать 10+ запросов для одного экрана.

Ответственности Gateway: аутентификация (JWT валидация один раз, не в каждом сервисе), rate limiting, SSL termination, request routing, response aggregation (Backend for Frontend паттерн - разные Gateway для mobile и web с разным агрегированием), circuit breaking, request/response трансформация. Риск: Gateway становится bottleneck и single point of failure. Решение: horizontal scaling и строгое ограничение бизнес-логики в Gateway.

Зачем JWT аутентификацию лучше выполнять в API Gateway, а не в каждом микросервисе отдельно?

Saga Pattern

Saga - паттерн для управления распределёнными транзакциями без 2PC (Two-Phase Commit). В микросервисах нет единой базы данных - каждый сервис со своей. Атомарная транзакция через несколько сервисов невозможна в классическом смысле. Saga решает это через последовательность локальных транзакций с compensating actions при неудаче.

Два вида Saga: Choreography (каждый сервис слушает события и публикует следующие - децентрализованно, сложно отследить общий flow) и Orchestration (центральный оркестратор знает весь flow и направляет сервисы командами - проще понять, single point). Uber Eats использует Saga для оформления заказа: Payment -> Restaurant -> Delivery - каждый шаг может откатиться с compensating action.

В Saga при оформлении заказа: Payment прошёл, Inventory.reserve() упал с ошибкой. Какой compensating action нужен?

Circuit Breaker

Circuit Breaker - паттерн предотвращения каскадных отказов. Называется по аналогии с электрическим автоматическим выключателем. Когда зависимый сервис начинает отвечать медленно или с ошибками - Circuit Breaker 'размыкает цепь': следующие запросы немедленно получают ошибку (fail fast) вместо ожидания timeout. Это предотвращает исчерпание thread pool и задержку в caller сервисе.

Три состояния: Closed (нормальная работа, запросы проходят), Open (цепь разомкнута, запросы fail fast - определяется порогом ошибок), Half-Open (пробный запрос - если успешен, переход в Closed; если неудачен - обратно в Open). Netflix Hystrix был первой popular реализацией (сейчас maintenance mode). Resilience4j для Java, Polly для .NET. Параметры: порог ошибок (50%), timeout для полуоткрытого состояния (10 сек).

Payment Service отвечает за 5 секунд вместо обычных 100ms. Order Service ждёт каждого запроса. Что происходит без Circuit Breaker?

Service Mesh

Service Mesh - инфраструктурный слой для управления коммуникацией между микросервисами. Реализуется через sidecar proxy (Envoy) рядом с каждым сервисом - перехватывает весь трафик. Приложение не знает о mesh: оно обращается к localhost, sidecar обрабатывает routing, retry, circuit breaking, mTLS, observability. Istio и Linkerd - самые распространённые реализации.

Service Mesh решает cross-cutting concerns без изменения кода сервисов: mutual TLS между всеми сервисами (zero trust networking), automatic retry с exponential backoff, circuit breaking на уровне инфраструктуры, distributed tracing (каждый запрос получает trace ID), traffic splitting для canary deployments (10% трафика в новую версию через routing rules). Lyft разработал Envoy именно для этих задач в своей микросервисной архитектуре.

Service Mesh решает все проблемы микросервисов - после его внедрения сервисы не нужно беспокоиться о network failures

Service Mesh обрабатывает network-level concerns (retry, circuit breaking, mTLS), но бизнес-логика обработки отказов (fallback данные, graceful degradation) остаётся в коде сервисов

Mesh не знает что вернуть пользователю когда Payment Service недоступен. Показать кешированный баланс? Заблокировать покупку? Это бизнес-решение, не инфраструктурное

Circuit Breaker уже реализован в коде Order Service через Resilience4j. Нужно ли добавлять circuit breaking ещё и в Service Mesh (Istio)?

Связанные темы

Паттерны микросервисов решают конкретные проблемы distributed systems:

  • Event Sourcing и CQRS — Saga Choreography использует domain events для координации между сервисами без центрального оркестратора
  • Монолит vs Микросервисы — Паттерны API Gateway и Circuit Breaker нужны именно из-за распределённости - в монолите эти проблемы не возникают

Вопросы для размышления

  • Saga Choreography vs Orchestration: какие trade-offs определяют выбор для конкретного use case?
  • Circuit Breaker с fallback к кешированным данным: когда устаревшие данные лучше чем ошибка, а когда нет?
  • Service Mesh добавляет sidecar к каждому поду - это latency overhead и complexity. Когда это оправдано?

Связанные уроки

  • net-53-distributed-intro
Микросервисы: паттерны

0

1

Войти