Недостатки микросервисной архитектуры
Микросервисная архитектура (MSA) — подход, когда система разбивается на небольшие независимые сервисы. У MSA есть недостатки, которые важно учитывать при проектировании.
1. Сложность управления распределёнными транзакциями
Проблема. В монолите транзакции управляются на уровне БД (ACID). В MSA данные распределены, и обеспечение согласованности требует сложных решений.
Пример: заказ оформлен, платёж прошёл, но товар не списался — пользователь заплатил за несуществующий товар.
Решения:
- Saga-паттерны: реализуют оркестрацию или хореографию транзакций с л окальными шагами и компенсациями
- Outbox-паттерн: позволяет гарантировать отправку событий в шину сообщений после успешной локальной транзакции
2. Задержки из-за сетевых вызовов
Проблема. Межсервисные вызовы (HTTP, gRPC, AMQP) добавляют сетевые задержки, что может привести к ухудшению UX.
Пример: открытие страницы профиля пользователя требует вызовов к 10 сервисам — итого 1+ секунда задержки.
Практики:
- Кеширование на уровне API Gateway или Edge Cache
- Bulk- или фреймворк-запросы (например, GraphQL)
- Асинхронная обработка через сообщения и очереди
3. Оверхеды мониторинга и трассировки
Проблема. При десятках и сотнях сервисов сложно локализовать источник ошибки и собрать полную картину работы.
Пример: пользователь видит ошибку при оформлении заказа — неизвестно, виноват Cart, Orders или Payments.
Практики:
- Distributed Tracing (Jaeger, Zipkin, OpenTelemetry)
- Централизованные логи (ELK Stack, Loki)
- Метрики и алерты (Prometheus + Grafana)
4. Сложность тестирования и развёртывания
Проблема. Каждый сервис может иметь свою БД, конфигурацию и зависимости. Интеграционное тестирование всей системы требует поднятия множества сервисов.
Пример: тест Cart Service требует запуска Users, Products и Discounts — иначе тесты падают.
Практики:
- Контракты (Contract Testing): Pact, Spring Cloud Contract
- Mock-сервисы и виртуализация (WireMock, Hoverfly)
- Изолированные сценарии на уровне эндпоинтов
5. Дублирование данных и согласованность
Проблема. Каждый сервис хранит свою копию данных → возможны расхождения.
Пример: пользователь обновил email, но в Order History отображается старый адрес.
Практики:
- Event Sourcing и CQRS: разделяют чтение и запись и обеспечивают последовательность событий
- Change Data Capture (CDC): синхронизирует данные между БД через Kafka Connect или Debezium
6. Усложнение безопасности
Проблема. Требуется управлять аутентификацией и авторизацией в каждом сервисе, защищать межсервисный обмен данными.
Пример: забыли настроить проверку токена в одном из сервисов — появляется уязвимость.
Практики:
- API Gateway как точка авторизации
- OAuth2 / OpenID Connect, JWT-токены
- mTLS для коммуникации между сервисами
7. Проблемы проектирования границ сервисов
Проблема. Неправильное разбиение может привести к сильной связанности и усложнить сопровождение.
Пример: один сервис содержит и авторизацию, и профиль, и логи — изменить что-то без риска сложно.
Практики:
- Использовать Domain-Driven Design (DDD) и Bounded Contexts
- Анализировать частоту изменений: если два модуля часто меняются вместе — возможно, они должны быть одним сервисом
- Проводить ревью доменных моделей и пересматривать границы по мере роста системы