Экономика микросервисов: когда объединять, а когда разъединять

Экономика микросервисов: когда объединять, а когда разъединять

Вы когда-нибудь сталкивались с ситуацией, когда новый фича в вашем приложении требовала полной пересборки всего сервиса, потому что одна маленькая логика была завязана на десяток других? Или когда вы тратили неделю на настройку деплоя, потому что микросервисы начали «дрожать» от нагрузки? Это не «технический долг» — это экономика микросервисов, которая уже не работает.

Микросервисы — не панацея. Они не делают систему «лучше» по умолчанию. Они делают её иначе. И если вы не понимаете, когда их объединять, а когда разъединять — вы платите за них в виде времени, денег и стресса, не получая обратной выгоды.

Зачем вообще делить на микросервисы?

Классический ответ: «чтобы масштабировать». Но на практике масштабирование — это последний аргумент. Первый — независимость команд.

Представьте: у вас есть команда, которая отвечает за оплату. Вторая — за доставку. Третья — за уведомления. Если всё это в одном монолите, то любое изменение в оплате требует тестирования всей системы. Даже если вы не трогали доставку. Даже если вы не трогали уведомления. И вы вынуждены координировать релизы, делать сложные мерж-реквесты, ждать, пока все тесты пройдут. Это замедляет всё.

Если же у вас три отдельных сервиса — каждая команда может деплоить, когда хочет. Тестирует только свой сервис. Выпускает фичи по своему графику. Это даёт скорость. И это — главная причина, по которой микросервисы существуют.

Но есть обратная сторона. Каждый сервис — это:

  • Отдельный деплой
  • Отдельная база данных (если вы делаете это правильно)
  • Отдельная сеть, маршрутизация, мониторинг
  • Отдельный процесс обработки ошибок
  • Отдельный лог, отдельные алерты

И всё это стоит. Не в деньгах на серверы — а в времени инженеров. Времени на настройку CI/CD. Времени на отладку распределённых транзакций. Времени на понимание, почему запрос упал, если он прошёл через пять сервисов.

Когда микросервисы — это перерасход

Самая частая ошибка: делить сервисы по «логическим блокам», даже если они не нужны в отдельности.

Пример: вы делаете интернет-магазин. У вас есть:

  • Каталог товаров
  • Корзина
  • Оформление заказа
  • Оплата
  • Уведомления

Вы решаете: «Каталог — отдельный сервис. Корзина — отдельный. Оформление — отдельный». И тут же получаете:

  • При открытии страницы товара — 3 HTTP-запроса: каталог, корзина, уведомления о статусе
  • При добавлении в корзину — 2 вызова: корзина + каталог (чтобы проверить наличие)
  • При оплате — 4 вызова: корзина, каталог, оплата, уведомления

Задержка страницы: 1.2 секунды. А вы хотите, чтобы она грузилась за 300 мс.

Или другой сценарий: вы запускаете MVP. 3 человека в команде. 1 бэкенд, 1 фронт, 1 QA. Вы делаете 5 микросервисов. Каждый из них требует:

  • Настройка Docker
  • Настройка CI/CD
  • Настройка мониторинга
  • Настройка логов
  • Настройка межсервисного вызова

Вы тратите 3 недели на инфраструктуру. А за это время можно было бы сделать 2 полноценных фичи в монолите.

Микросервисы — это не про «правильную архитектуру». Это про экономию времени команды при росте сложности. Если сложность ещё не вышла за пределы того, что одна команда может удерживать — вы платите за них впустую.

Когда микросервисы — это спасение

Вот когда они работают:

  1. Команда растёт — у вас 5+ инженеров, и они работают в разных направлениях. Если вы не разделите сервисы, вы будете тормозить друг друга.
  2. Разные требования к масштабированию — например, каталог товаров читают 10 000 раз в секунду, а админка — 10 раз. Вы не можете масштабировать всё вместе.
  3. Разные технологии — оплата требует строгой согласованности (PostgreSQL), а уведомления — высокой пропускной способности (Kafka + Redis). Вы не можете использовать один стек для всего.
  4. Разные сроки релизов — вы не хотите ждать, пока бухгалтерия одобрит изменение в логике уведомлений.
  5. Сервисы могут быть проданы или вынесены отдельно — например, вы делаете платформу для магазинов, и ваша система оплаты — отдельный продукт для клиентов.

Если ни один из этих пунктов не применим — вы, скорее всего, делаете микросервисы ради «модного» стека, а не ради выгоды.

Таблица: когда объединять, а когда разъединять

Критерий Объединять в один сервис Разъединять на микросервисы
Количество команд 1–2 инженера 3+ команды, работающие независимо
Скорость релизов Релизы раз в 2–4 недели Нужно деплоить несколько раз в день
Сложность системы Меньше 10 000 строк кода на бэкенде Более 20 000 строк, с множеством зависимостей
Зависимости между модулями Модули часто меняются вместе, используют общие данные Модули работают независимо, редко пересекаются
Требования к масштабированию Все части нагружены одинаково Одна часть требует в 10–100 раз больше ресурсов
Срок жизни продукта MVP, стартап, проверка гипотезы Продукт живёт 2+ года, растёт по пользовательской базе
Ошибки в работе Ошибки легко локализовать, 1–2 лога на весь сервис Ошибки возникают в цепочке вызовов, требуют трассировки

Эти ориентиры не абсолютны — но они работают в 80% случаев. Если вы видите, что у вас 3 команды, но вы всё ещё держите всё в одном сервисе — вы тормозите рост. Если у вас 1 команда и 7 сервисов — вы тратите 40% времени на инфраструктуру вместо разработки.

Частые ошибки

Вот что ломает микросервисы на практике:

  • «Сервисы по таблицам БД» — вы сделали отдельный сервис для «пользователей», «заказов», «товаров». Это не микросервисы — это монолит, разбитый на части. В реальности вы получаете 100+ межсервисных вызовов на один экран, и ни одного преимущества.
  • «Все сервисы — одинаковые» — вы используете один стек (Node.js + PostgreSQL) для всех, даже если для уведомлений лучше подошёл Go + Redis. Это не гибкость — это догма.
  • «Мы не будем использовать общую базу» — и потом делаем 5 копий данных — вы копируете пользователей в 4 сервиса, чтобы не делать вызов. Это не масштабируемость — это ужасный дубль, который потом надо синхронизировать. Или вы получаете «состояние согласованности» через 30 минут — и клиенты жалуются, что у них в корзине товар, которого уже нет.
  • «Мы сделаем 20 сервисов, потому что так модно» — это как покупать 20 кухонных комбайнов, потому что «все их используют». Вы не увеличите производительность — вы просто усложните себе жизнь.
  • «Мы не будем мониторить» — если вы не знаете, какой сервис упал, когда и почему — вы не можете поддерживать микросервисы. Без трассировки (OpenTelemetry), логов (Loki), метрик (Prometheus) и дашбордов (Grafana) — вы слепы.

Как лучше сделать

Вот пошаговый подход, который я использую на практике:

  1. Начните с монолита. Даже если вы знаете, что в будущем будете переходить на микросервисы — начните с одного проекта. Это даст вам ясность: что реально связано, а что нет.
  2. Соберите метрики. Сколько вызовов происходит между модулями? Какие модули чаще всего меняются вместе? Какие части системы чаще всего ломаются? Используйте логи, профайлеры, APM-инструменты. Без данных вы делаете предположения.
  3. Разделяйте только то, что действительно независимо. Если два модуля меняются вместе — оставьте их вместе. Если один модуль использует данные другого, но не меняет их — подумайте, можно ли просто кешировать данные, а не делать отдельный сервис.
  4. Определите границы домена. Не делите по техническим компонентам — делите по бизнес-доменам. Например: «оплата», «доставка», «поддержка клиентов». Каждый домен — это автономная сущность с понятной ответственностью.
  5. Сделайте один сервис — и посмотрите, как он работает. Не делайте 5 сразу. Сделайте один, поставьте мониторинг, настройте деплой, протестируйте. Если через месяц вы не увидели прироста скорости или снижения ошибок — вы сделали ошибку.
  6. Используйте API-контракты. Даже если сервисы внутри одного репозитория — определите чёткие интерфейсы. Это снизит связность и облегчит будущее разделение.

Что выбрать в зависимости от ситуации

Вот сценарии — и что делать в каждом:

  • Вы стартап. 2 человека. Нужно запустить MVP за 3 недели. — Делайте монолит. Всё в одном репозитории. Одна база. Один деплой. Не тратьте время на Docker и Kubernetes. Потом, когда будет 50 000 пользователей — вы поймёте, где нужно делить.
  • У вас 100 000 пользователей. Команда из 8 человек. Два раза в неделю вы ломаете что-то при деплое. — Начните с разделения по доменам. Выделите «оплату» и «уведомления» — они наиболее независимы. Остальное — пока в монолите. Следите за тем, сколько времени тратится на деплой и тестирование. Если после разделения вы экономите 10+ часов в неделю — вы на правильном пути.
  • Вы делаете SaaS-платформу для бизнеса. Клиенты хотят включать/отключать модули. — Делите по модулям. Каждый модуль — отдельный сервис. Это даёт гибкость: один клиент использует только оплату, другой — только аналитику. Вы можете продавать модули отдельно.
  • Вы переписываете legacy-систему. Она работает, но никто не понимает, как. — Не делайте микросервисы сразу. Сделайте «стратификацию»: выделите один слой (например, оплату) и перепишите его отдельно. Остальное — оставьте как есть. Постепенно заменяйте части. Это называется «стрangler pattern» — и это безопаснее, чем полный рефакторинг.

Рекомендации: как не сгореть

Вот что реально помогает:

  • Максимум 3–5 микросервисов на команду. Если у вас 5 инженеров — не делайте 10 сервисов. Это перегрузка.
  • Один сервис — одна база данных. Если вы делите данные — вы делаете микросервисы. Если вы делите сервисы, но используете одну базу — вы делаете монолит с лишними слоями.
  • Создайте «сервисный шаблон». Один шаблон для всех сервисов: одинаковые логи, одинаковые метрики, одинаковые правила деплоя. Это снижает когнитивную нагрузку.
  • Не используйте gRPC, если HTTP/REST работает. gRPC сложнее, тяжелее в отладке. Не делайте сложнее, чем нужно.
  • Платите за микросервисы в виде времени. Если вы тратите 20% времени на настройку инфраструктуры — это нормально. Если 50% — вы перешли в зону перерасхода.

Итог: что делать прямо сейчас

Вот ваша проверка:

  1. Сколько людей работает над этим продуктом? Если меньше трёх — не делите.
  2. Как часто вы сталкиваетесь с тем, что изменения в одном месте ломают другое? Если чаще 1 раза в неделю — пора думать о разделении.
  3. Есть ли у вас метрики? Если нет — соберите их за неделю. Посмотрите, какие модули чаще всего меняются вместе. Если 3 из 5 меняются вместе — оставьте их вместе.
  4. Если вы собираетесь масштабировать — на что? На пользователей? На команду? На функциональность? Если на команду — делите. Если на пользователей — сначала оптимизируйте монолит.

Микросервисы — это не про «техническую красоту». Это про экономию времени, когда система становится слишком сложной для одной команды. Если вы не экономите время — вы теряете его.

Сегодня — проверьте: сколько часов в неделю вы тратите на координацию деплоев, отладку распределённых ошибок и настройку инфраструктуры? Если больше 10 — возможно, вы слишком много разделили. Если меньше 3 — возможно, вы слишком мало разделили.

Не делайте микросервисы потому, что «так надо». Делайте их потому, что они спасают вашу команду от собственной сложности.

Информация в этой статье носит ознакомительный характер. Принятие архитектурных решений требует анализа специфики вашего продукта, команды и бизнес-целей. Перед изменениями в инфраструктуре рекомендуется проконсультироваться с опытным инженером или архитектором.

dfncfg.ru — цифровой мир и технологии