Микросервисная архитектура
Определение. Микросервис — это автономный процесс, реализующий узкую бизнес-возможность, владеющий своими данными и взаимодействующий с другими сервисами по явным контрактам. Цель — добиться слабой связности между компонентами при высокой внутренней связности каждого сервиса, чтобы команды могли независимо разрабатывать, тестировать, развёртывать и масштабировать части системы.
Зачем это нужно: цели и идеи
Независимые поставки. Каждая команда выпускает изменения в своём сервисе без координации «больших релизов».
Изоляция рисков. Сбой одного сервиса не «роняет» всю систему при корректной деградации и таймаутах.
Выбор технологий. Разные сервисы могут использовать разные стеки, если это оправдано и не ломает операционную совместимость.
Масштабирование по компонентам. Нагруженные сервисы масштабируются независимо, экономя ресурсы.
Орг-соответствие. Архитектура отражает структуру команд (закон Конвея), уменьшая коммуникационные накладные расходы.
Ключевые принципы реализации
Автономия данных. Каждый сервис владеет собственной схемой и не делит таблицы с соседями.
Явные контракты. Общение только через API с обратной совместимостью и версионированием.
Синхронное vs асинхронное. Синхронные вызовы (HTTP/gRPC) — для «онлайн» путей; асинхронные очереди/шины — для интеграций и фоновых реакций.
Идемпотентность. Повторная обработка сообщений и запросов не должна менять результат непредсказуемо.
Наблюдаемость по умолчанию. Логи, метрики и трассировки — часть функциональных требований.
Операционная готовность. Здоровье, readiness/liveness-пробы, сводные SLO и алерты — сразу в первый релиз.
Автоматизация. CI/CD, неизменяемые образы, декларативная инфраструктура и миграции данных.
Безопасность по умолчанию. Недоверие по умолчанию, mTLS, наименьшие привилегии, безопасное хранение секретов.
Как выбирать границы сервисов
Режьте систему по предметным возможностям и потокам данных, а не по техническим слоям (не «контроллеры», «репозитории», а «Платёж», «Каталог», «Доставка»). Учитывайте частоту изменений: то, что меняется вместе, должно жить вместе.
У каждого сервиса — собственная база, договорённости на уровне событий/контрактов.
Минимизируйте «сквозные» транзакции — вместо этого проектируйте локальные инварианты и чёткие реакции на факты.
Проверка границ: может ли сервис быть временно недоступен без обрушения пользовательского сценария? Если нет — границы выбраны плохо.
Коммуникации между сервисами
Синхронные вызовы упрощают запрос-ответ, но удлиняют критический путь: каждая новая «стыковка» увеличивает P95/таймауты. Асинхронные взаимодействия повышают устойчивость и разгружают фронт, но требуют проектирования доставки, повторов и порядка.
Контракты и версии. Не ломайте существующих потребителей: вводите
/v2
как отдельный контракт.Таймауты и повторы. Любая сеть ненадёжна: задавайте конечные таймауты, ограниченные ретраи и идемпотентные операции.
Корреляция. Передавайте Correlation-ID сквозь все вызовы.
Данные и согласованность
Глобальных транзакций в распределённых системах лучше избегать: они хрупки и медленны. Проектируйте локальные транзакции в пределах сервиса и механизмы уведомления соседей о «свершившихся фактах». Принимайте согласованность в итоге там, где это допустимо бизнесом.
Каждое изменение фиксируется локально, а затем доносится до других сервисов сообщением/вебхуком.
Получатели обязаны уметь безопасно обрабатывать повторы и внепорядковость.
Критичные инварианты (например, «баланс не уходит в минус») должны сохраняться локально, без внешних вызовов.
Деплой и инфраструктура
Стандартная операционная база: сервисы согласно доменной модели, по базе для каждого сервиса и многие другие участники микросервисной инфраструктуры. Поставляйте неизменяемые образы и конфигурации как код.
Наблюдаемость и эксплуатация
Производственная готовность включает три столпа: логи, метрики, трассировки. Определите целевые SLO, на их основе стройте алерты и бюджет ошибок.
Логи: структурированные, с полями запроса/пользователя/корреляции.
Метрики: латентность, частота ошибок, насыщение ресурсов.
Трассировки: единый Correlation-ID на весь путь запроса.
Тестирование и качество
Юнит-тесты для предметной логики внутри сервиса.
Контрактные тесты потребителя и поставщика API, чтобы ловить несовместимые изменения.
Интеграционные тесты с локальными зависимостями (контейнеры/фейки), чтобы сценарии были воспроизводимыми.
E2E — немного и по критическим путям, иначе они станут хрупкими и медленными.
Безопасность
Аутентификация и авторизация на границе (шлюз) и внутри (межсервисные токены).
Шифрование на транспорте (mTLS) и в покое.
Секреты только в менеджере секретов, с ротацией.
Аудит действий и доступов.
Когда стоит и когда нет
Подходит, если много команд, быстрые релизы, высокие требования к масштабированию и изоляции отказов.
Не подходит, если домен простой, команда мала, а основные проблемы — в качестве кода и процессах, а не в архитектуре.
Чек-лист внедрения
Цели и ожидаемые метрики (скорость релизов, P95, надёжность).
Карта домена и кандидаты на сервисные границы.
Стандарты контрактов и версионирования.
Стратегии коммуникаций (где синхронно, где асинхронно).
Владение данными и правила согласованности.
Базовая наблюдаемость и пороговые SLO.
CI/CD, окружения, миграции, откаты.
Модель безопасности и работа с секретами.
Runbook и он-колл: кто, как и чем реагирует.
Мини-пример: идемпотентный запрос
Создание заказа должно безопасно переживать повторную отправку клиента/ретраи сети. Контракт вводит заголовок Idempotency-Key
, по которому сервер распознаёт дубликаты.