Оглавление
Время чтения: 6 минут
Кейс: как перейти от микросервисов к монолиту грамотно
Привет! В этой статье я расскажу о нашем опыте перехода от микросервисной архитектуры обратно к монолиту. На практике часто слышишь истории про переход с монолита на микросервисы, но обратный путь встречается гораздо реже. Тем не менее, он не менее важен и полезен для понимания, когда и почему стоит пересмотреть архитектурный подход, даже если кажется, что поздно.
Исходная ситуация
При выборе между микросервисами и монолитом многие склоняются к микросервисам — они удобнее для масштабирования, хорошо подходят для высоконагруженных проектов и легко адаптируются под быстро меняющиеся требования. В нашем случае тоже изначально был проект, задумывавшийся как гибкий и быстрорастущий сервис, который должен был оперативно проверять гипотезы и масштабироваться.
Проект возник как объединение двух разных систем: контентного сайта с мобильным приложением и CRM-системы для автоматизации работы клиник. Изначально они работали независимо, но бизнес предположил, что их интеграция поможет увеличить трафик и эффективность.
Развитие микросервисной архитектуры
Поскольку проект был стартапом, основная задача заключалась в быстрой проверке гипотез. Микросервисы отлично подходили для этого — каждая часть системы имела ограниченную и чётко очерченную область ответственности.
Однако по мере роста продукта появились новые задачи — например, расширение функционала CRM для записи пользователей в клиники. Чтобы связать разные части системы, мы реализовали взаимодействие через REST API с разными уровнями детализации данных (минимальный, короткий, максимальный и расширенный наборы полей), что привело к усложнению контроллеров и росту технического долга.
Проблемы микросервисов и попытки стандартизации
С увеличением количества сервисов возникли сложности с согласованностью данных, дублированием логики и необходимостью поддержки одинаковых запросов во многих сервисах. Для решения этих проблем мы создали единый SDK, который стандартизировал общие запросы и ответы, а также вынес базовые компоненты в отдельный модуль для уменьшения дублирования.
Тем не менее, реализация новых функций и поддержка старых сервисов шли неравномерно: старые сервисы оставались без должного рефакторинга, что усложняло стандартизацию и сопровождение.
Почему решили перейти к монолиту
Несмотря на все преимущества микросервисов, нагрузка на проект оказалась ниже ожидаемой, и возможности использовать разные технологии для отдельных сервисов практически не понадобились. Кроме того, инфраструктурные решения (например, Kubernetes или Docker Swarm) отсутствовали, что усложняло процесс CI/CD и увеличивало время поддержки.
Проект, хоть и имел зрелость, по-прежнему требовал быстрой реакции на изменения бизнеса, что оказалось сложно поддерживать в микросервисной архитектуре. В итоге мы пришли к выводу, что разделение функций, тесно связанных друг с другом, на разные сервисы не оправдано и неудобно.
Переход к монолиту
Мы начали с попытки объединить наиболее сложный API и постепенно перенесли весь функционал в единую систему, используя современный фреймворк. Поначалу возникла путаница с организацией кода и структурой проекта: трудно было отделить отдельные функции, появлялись дублирующие классы и сущности.
Для решения этой проблемы мы ввели концепцию доменных областей и гейтвеев внутри монолита — то есть каждый блок отвечал за свою часть функционала, но в рамках одного проекта. Это позволило гибко управлять кодом, уменьшить объём дублирования и сохранить независимость разных частей системы.
Какие сложности встретились
Одним из главных минусов стал рост дублирования, особенно для функционала, работающего как в мобильной, так и в веб-версии. При этом архитектура оставалась достаточно гибкой, чтобы быстро вводить новые функции и проверять гипотезы.
Также изменения в интерфейсе пользователя часто требовали корректировок в бэкенде — например, изменение формата данных или добавление новых контроллеров, что увеличивало объём поддержки.
Итоги и выводы
В итоге мы получили гибридную архитектуру: ядро системы — монолит, а отдельные независимые сервисы (например, аналитика, уведомления, хранение файлов) остались микросервисами. Такой подход позволил сохранить преимущества микросервисов в нужных местах и упростить разработку и поддержку основных функций.
Основные плюсы нового подхода:
- Сохранилась гибкость и возможность быстрой проверки бизнес-гипотез.
- Упростилась инфраструктура и CI/CD.
- Снизилась сложность сопровождения и стандартизировалась логика.
- Сэкономились ресурсы.
Проект не был сильно нагружен, а затраты на поддержку микросервисов оказались высокими. Перевод ядра в монолитную архитектуру позволил эффективно управлять продуктом и быстрее реагировать на изменения.
Заключение
Микросервисы — это не панацея, а дополнительный уровень сложности. Их гибкость и масштабируемость сопровождаются проблемами синхронизации данных, сложностью трассировки и увеличенными требованиями к инфраструктуре.
Поэтому на старте важно тщательно оценивать задачи и масштаб проекта. Даже если микросервисы кажутся подходящим решением, для MVP и многих проектов лучше начать с монолита и переходить к сервисам по мере необходимости.