1. Микросервисная архитектура: паттерны декомпозиции, DDD и межсервисное взаимодействие
Микросервисная архитектура: паттерны декомпозиции, DDD и межсервисное взаимодействие
Приветствую, коллега. Если вы читаете этот курс, значит, вы уже переросли задачи уровня «написать контроллер и сохранить сущность в базу». Вы хотите строить системы, которые выдерживают высокие нагрузки, легко масштабируются и не падают от одного неверного коммита. Путь от Middle Java Developer до Architect лежит через понимание того, как и почему мы разделяем системы на части.
Сегодня мы разберем фундамент современной разработки — микросервисную архитектуру. Мы не будем говорить о Kubernetes или Docker (это инструменты), мы будем говорить о принципах проектирования.
От Монолита к Микросервисам: Зачем нам это нужно?
Монолитная архитектура — это не плохо. Для стартапов и небольших проектов это часто лучший выбор. Однако, когда команда растет до 50+ человек, а кодовая база компилируется 20 минут, монолит становится узким местом. Любое изменение требует пересборки всего приложения, а ошибка в модуле отчетности может положить модуль оплаты.
Микросервисы решают эти проблемы за счет слабой связности (Low Coupling) и высокой сцепленности (High Cohesion) внутри сервиса.
!Сравнение структуры зависимостей в монолите и микросервисах
Однако микросервисы приносят сложность распределенных систем. Надежность системы, состоящей из множества зависимых компонентов, рассчитывается иначе. Если у нас есть цепочка синхронных вызовов, общая надежность падает.
Рассмотрим формулу надежности последовательной цепи сервисов:
Где:
Если у вас 5 сервисов, каждый с надежностью 99% (), то общая надежность цепочки будет . То есть 5% запросов упадут. Это математическое обоснование того, почему в микросервисах нужно избегать длинных цепочек синхронных вызовов.
Domain-Driven Design (DDD) как база для декомпозиции
Самый частый вопрос при переходе на микросервисы: «Как правильно распилить монолит?». Ответ кроется не в технической плоскости, а в бизнесе. Здесь нам помогает Domain-Driven Design (DDD) — предметно-ориентированное проектирование.
Главная ошибка — делить сервисы по техническому признаку (сервис авторизации, сервис логирования, сервис работы с БД). Правильный подход — делить по бизнес-капабилити (Business Capability).
Bounded Context (Ограниченный контекст)
Центральное понятие DDD. Это граница, внутри которой определенная модель предметной области имеет строгий смысл.
Например, понятие «Товар» () в интернет-магазине:
В монолите мы часто пытаемся создать один класс Product на 500 полей, который удовлетворяет всех. В микросервисах мы создаем три разных сервиса (Каталог, Склад, Бухгалтерия), каждый со своей моделью данных. Они общаются только через ID товара.
Паттерны декомпозиции
1. Decompose by Business Capability
Сервисы создаются вокруг бизнес-функций. Например: Управление заказами, Управление клиентами, Доставка. Это самый интуитивный способ, часто совпадающий с организационной структурой компании (закон Конвея).2. Decompose by Subdomain
Более строгий подход из DDD. Мы выделяем: * Core Subdomain (Ядро): То, что приносит деньги и отличает бизнес от конкурентов. * Supporting Subdomain (Вспомогательный): Необходим для работы, но не является конкурентным преимуществом. * Generic Subdomain (Общий): Типовые задачи (почта, авторизация), которые можно купить или взять готовые.3. Strangler Fig (Удушение)
Паттерн миграции. Мы не переписываем монолит с нуля. Мы ставим перед ним фасад (API Gateway). Новые функции пишем как микросервисы. Старые функции постепенно выносим из монолита в новые сервисы, переключая трафик на Gateway. Со временем монолит «удушается» и исчезает.!Визуализация постепенной замены монолита микросервисами
Межсервисное взаимодействие
Когда мы разделили систему, встает вопрос: как сервисам общаться? Существует два основных типа взаимодействия.
Синхронное взаимодействие (Request/Response)
Клиент отправляет запрос и ждет ответа. * Протоколы: HTTP (REST), gRPC. * Плюсы: Простота реализации, предсказуемость. * Минусы: Блокировка потока, жесткая связность (coupling), каскадные сбои (вспоминаем формулу надежности выше).Асинхронное взаимодействие (Event-Based)
Клиент отправляет сообщение и забывает (Fire and Forget). Получатель обрабатывает его, когда сможет. * Инструменты: Kafka, RabbitMQ, ActiveMQ. * Плюсы: Слабая связность, сглаживание пиковых нагрузок (Backpressure), высокая доступность. * Минусы: Сложность отладки, Eventual Consistency (согласованность в конечном счете).> «В распределенных системах асинхронное взаимодействие должно быть выбором по умолчанию, а синхронное — исключением».
Распределенные транзакции и Саги
В монолите у нас была роскошь ACID-транзакций базы данных. В микросервисах база у каждого своя. Как гарантировать, что если деньги списались, то заказ создался?
Используется паттерн Saga — последовательность локальных транзакций. Если на каком-то шаге происходит ошибка, выполняются компенсирующие транзакции (откат изменений).
Существует два вида координации саг:
1. Хореография (Choreography)
Сервисы обмениваются событиями без центрального управления. Сервис Заказов* публикует событиеOrderCreated.
Сервис Оплаты* слушает его, списывает деньги и публикует PaymentProcessed.
Если ошибка — публикуется PaymentFailed, и Сервис Заказов* отменяет заказ.Плюсы: Простота, слабая связность. Минусы: Сложно отследить логику процесса, риск циклических зависимостей.
2. Оркестрация (Orchestration)
Есть отдельный сервис (Оркестратор), который говорит другим, что делать. Оркестратор вызывает Сервис Заказов*. Оркестратор вызывает Сервис Оплаты*. * Если ошибка — Оркестратор вызывает методы отмены.Плюсы: Логика централизована, проще контроль. Минусы: Оркестратор может стать «Божественным сервисом» с лишней логикой.
!Сравнение подходов Хореографии и Оркестрации в паттерне Saga
Итоги
Переход к микросервисам — это не просто смена технологий, это смена мышления. Вы должны научиться:
В следующих статьях мы углубимся в детали реализации: разберем Kafka как позвоночник событийной архитектуры и посмотрим, как правильно готовить PostgreSQL в высоконагруженной среде.