Почему микросервисы — плохой выбор для старта? Или как не утопить проект в техническом долгу.

Почему микросервисы — плохой выбор для старта? Или как не утопить проект в техническом долгу.

Микросервисы стали настоящим символом современной разработки. Все хотят иметь гибкую, масштабируемую архитектуру, состоящую из маленьких независимых изолированных сервисов. Идея выглядит простой и привлекательной: небольшие независимые команды работают над отдельными сервисами, быстро выпускают обновления, легко поддерживают и развивают систему.

Но часто при выборе микросервисной архитектуры на старте проекта, особенно на этапе MVP, эта мечта превращается в кошмар. И тогда происходит деградация архитектуры системы в несколько этапов.

Старт: «Мы не знаем, что строим, но уже делим на сервисы»

На старте домен еще не определен. Мы пытаемся угадать, какие части системы будут автономными, но это похоже на путешествие в темноте.

Что происходит:

  • Неправильные границы сервисов - часто границы проводятся технически (по типу сущностей: "вот сервис Пользователей", "вот сервис Заказов"), а не по бизнес-возможностям.
  • Скрытые зависимости - даже если сервисы формально разделены, изменения в бизнес-логике часто требуют правок в нескольких местах. Вместо гибкости мы получаем необходимость координировать изменения между командами, тестировать интеграции и бояться релизов.
  • Сложная инфраструктура с нуля - микросервисы требуют CI/CD для каждого сервиса, мониторинг, логирование, управление конфигурациями, контейнеризацию и оркестрацию (Kubernetes, Docker). Но наш MVP ещё даже не окупился, а команда уже тратит время на настройку кластеров вместо того, чтобы тестировать гипотезы.

Рост: «Мы знаем больше, но уже поздно что-то менять»

Когда проект переходит в фазу пост MVP мы начинаем понимать, как должен выглядеть продукт. Но микросервисы, созданные в спешке, начинают нас тормозить.

Что происходит:

  • Несостоявшиеся автономность и масштабируемость - мы планировали, что некоторые сервисы будут работать независимо, но теперь они обмениваются данными через API каждые 5 минут. Масштабирование одного сервиса требует масштабирования другого, потому что нагрузка на них связана. Вместо экономии на ресурсах вы получаете рост затрат без реальной пользы.
  • Технический долг, который висит мертвым грузом - каждое изменение в домене (например, новые правила валидации) требует переписывать API между сервисами. Мы добавляем адаптеры, мапперы, шлюзы — и в итоге получаем сложную систему, которую трудно поддерживать. Новые разработчики месяцами разбираются в зависимостях, а старые боятся трогать «рабочее» решение.
  • Кошмар с транзакциями и согласованностью - в монолите мы могли использовать ACID-транзакции для обеспечения целостности данных. В микросервисах приходится мириться с eventual consistency или писать сложные механизмы SAGA. Ошибка в одном шаге может оставить систему в несогласованном состоянии, а восстановление — это боль.

Зрелость: «Мы хотим переделать всё, но боимся»

Когда проект достигает зрелости, становится очевидно, что архитектура не соответствует реальным потребностям. Но переезд на новую структуру — это риск, время и деньги.

Что происходит:

  • Рефакторинг превращается в переписывание - чтобы исправить границы сервисов, необходимо переписать API, перенести данные, изменить интеграции. Это может занять месяцы, а мы не хотим останавливать развитие продукта.
  • Команды начинают "пробуксовывать" - микросервисы изолируют не только код, но и команды. Вместо быстрых решений мы получаем долгие обсуждения, формальные контракты API и конфликты интересов.
  • Масштабирование становится обузой - мы платим за инфраструктуру, которая изначально не была нужна. Вместо 100 строк кода в монолите мы тратим ресурсы на 10 сервисов, каждый из которых требует своего мониторинга и резервного копирования.

❓Что же тогда выбрать?

Если не микросервисы, то что? Обратно к громоздким монолитам? Ответ прост: стоит начать с чего-то более простого, но при этом дающего возможность для дальнейшего роста.

💡Выход есть: начните с модульного монолита

Микросервисы — это не про «масштабируемость ради масштабируемости», а про осознанное разделение на автономные части. Но чтобы к этому прийти, нужно сначала понять домен.

Модульный монолит — это компромисс, который даёт:

  • Гибкость на старте — вы делите код на модули с чёткими интерфейсами, но без сетевых проблем.
  • Контроль над зависимостями — проблемы в домене решаются внутри одной базы кода, без API-контрактов.
  • Путь к микросервисам — когда домен станет ясен, модули можно выделить в отдельные сервисы — по факту, а не вслепую.

Микросервисы — не точка входа, а точка выхода. Правильная архитектура — эволюционная. Многие популярные и авторитетные авторы — Мартин Фаулер, Роберт Мартин, Сэм Ньюман, Крис Ричардсон (и я очень поддерживаю их точку зрения) предлагают начинать разработку с монолитов.

Статья Фаулера (Martin Fowler) о "Monolith First" подходе

В следующем посте разберем подробно, что такое модульный монолит, как его правильно строить и какие подводные камни ждут на этом пути.

Мой телеграм-канал по ссылке: telegram

2 комментария