В битве между Монолитом, Микросервисами и Модульным монолитом — кто будет проигравшим?
Кто будет проигравшим?
Если вам когда-нибудь хотелось вкинуть холивар на встречу — просто спросите, какая архитектура лучше: монолит, микросервисы или модульный монолит. Затем отойдите на безопасное расстояние. В этой статье я проведу сравнение этих подходов с точки зрения системного аналитика, который отбил все места граблями и превратил это в ритуал.
Монолит: когда все яйца в одной корзине
Монолитная архитектура — это классический подход к разработке программного обеспечения, при котором все компоненты системы упакованы в один большой исполняемый файл. Представьте себе, что вся ваша система — это огромный комок пластилина из разных цветов, в котором запутались все функции, сервисы и зависимости.
«Работает — не трогай» — это не просто девиз, это способ сохранить свою психику в условиях абсолютной неопределенности монолитного кода.
Преимущества монолита (которые мы любим перечислять на собеседованиях):
- Простота разработки — весь код в одном месте, можно быстро найти любую функцию (если, конечно, вы носитель родоплеменного контекста)
- Легкость развертывания — просто скопировал файл и готово (если только ваш монолит не весит как фильм в HD)
- Отсутствие проблем с сетевыми вызовами — все функции вызываются напрямую (и падают тоже напрямую, без посредников)
- Единая транзакционная модель — ACID на всю систему
Недостатки монолита (о которых мы обычно узнаем на третий год разработки):
- Сложность поддержки — через год даже автор кода не помнит, как это работает
- Масштабирование только целиком — нельзя увеличить мощность только для части системы
- Сложность внедрения изменений — одно изменение может сломать всю систему (обычно в пятницу вечером)
- Технологическая жесткость — нельзя использовать разные технологии в разных частях системы (но зато все разработчики страдают одинаково)
Монолиты идеально подходят для стартапов и небольших проектов. «Мы быстро напишем MVP как монолит, а потом обязательно перепишем» — классическая легенда, которую все рассказывают на планировании первой версии. Спустя годы, эту фразу можно обнаружить только в архивных записях, о которых носитель контекста пытается не вспоминать, если еще не сменил проект.
Микросервисы: разделяй и… страдай?
Микросервисная архитектура — это подход, при котором система разбивается на множество небольших независимых сервисов, каждый из которых обслуживает одну конкретную функцию бизнеса. Это как если бы вы разделили дом на отдельные комнаты, а потом расставили их в разных частях города, соединив телефонными проводами.
Эффективно? Возможно. Сложно? Определенно.
Преимущества микросервисов:
- Независимое масштабирование — каждый сервис масштабируется отдельно (и каждый ломается отдельно, что удобно для поиска виноватых)
- Технологическая гибкость — разные сервисы на разных технологиях (зоопарк из технологий, что может пойти не так?)
- Более быстрая разработка — несколько команд могут работать параллельно (здоровья их Delivery Manager`у)
- Легкое внедрение изменений — изменение одного сервиса не влияет на остальные (пока не выясняется, что влияет, и еще как)
Недостатки микросервисов (о которых вспоминает ночной саппорт):
- Сложность инфраструктуры — нужно управлять десятками или сотнями сервисов
- Распределенные транзакции — согласованность данных превращается в отдельный вид искусства
- Сетевые задержки — каждый вызов между сервисами проходит по сети (и где-то там грустит пользователь, ожидая ответа)
- Сложность отладки — трассировка запроса через несколько сервисов похожа на путь по хлебным крошкам после дождика в четверг
«Давайте перейдем на микросервисы, как Netflix и Amazon!» — типичное предложение от разработчика, который прочитал статью в Medium, но никогда не поддерживал микросервисную архитектуру в промышленной эксплуатации. Следующая фраза обычно: «Сроки? Конечно, успеем к концу спринта!»
Модульный монолит: третий путь между крайностями
Между монолитом и микросервисами есть третий вариант — модульный монолит. Это компромисс: один артефакт деплоя, но внутри жёстко разделённые по bounded contexts модули с явными API. В этой статье мы оставляем его за скобками, потому что у него своя глубокая специфика — отдельные правила проектирования модулей, способы разделения базы и стратегия миграции к микросервисам.
Если вы выбираете именно между «один большой кусок кода» и «много мелких», то решение чаще всего лежит в плоскости монолит vs микросервисы — об этом и статья. А подробный разбор модульного монолита (включая bounded contexts, типичные ошибки и пример эволюции из обычного монолита) собран в отдельном руководстве по модульному монолиту.
Сравнительная таблица: монолит против микросервисов
| Критерий | Монолит | Микросервисы |
|---|---|---|
| Скорость разработки | Быстро в начале, потом «оно работает, не трогай» | Медленно в начале, потом «это другой сервис, не моё» |
| Масштабируемость | Только целиком (как любовь к начальнику — либо есть, либо нет) | Отдельными сервисами (как диета по дням недели) |
| Надёжность | Падает всё сразу (особенно в пятницу вечером) | Падает по частям (и обычно когда вы в отпуске) |
| Сложность инфраструктуры | Низкая (один сервер, одна молитва) | Высокая (Kubernetes кластер и шаманские бубны) |
| Когда объяснять начальству | «Так всегда делали» | «Так делают в Google» |
| Переиспользование кода | Легко (скопировал-вставил и забыл) | Сложно (отдельные библиотеки для каждой функции) |
| Транзакции | Локальные ACID — бесплатно | Распределённые саги, eventual consistency |
| Стоимость владения | Дешёво на старте, дорого через 3 года | Дорого на старте, предсказуемо в долгую |
Если в этом сравнении вам не хватает третьей колонки — посмотрите полное руководство по модульному монолиту, там модульный монолит разобран в деталях.
Ключевые выводы для тех, кто дочитал до конца (или сразу прокрутил сюда):
Монолит
- Выбирайте, если: у вас маленький проект, ограниченные ресурсы, нужно быстрее выйти на рынок и проверить идею
- Не выбирайте, если: у вас большая команда разработчиков, которые любят писать в одном файле одновременно и выяснять, чей коммит важнее
- Девиз: «Работает? Не трогай! Хотя, погоди, оно и не работало никогда…»
Микросервисы
- Выбирайте, если: у вас большая система с разными уровнями нагрузки, много команд и вы уже подписали контракт с AWS на крупную сумму
- Не выбирайте, если: у вас нет выделенной DevOps команды и бюджета на мониторинг, или вам нравится спать по ночам
- Девиз: «500 микросервисов и все равно никто не знает, где баг»
Если ни монолит, ни микросервисы не подходят на 100% — стоит посмотреть на гибрид. Подробнее в материале «Модульный монолит: архитектура, примеры и подводные камни».
И помните главное правило архитектора: какую бы архитектуру вы ни выбрали, через год вы всё равно будете жалеть о своём выборе.
Заключение
Выбирайте с улыбкой, живите здесь и сейчас. Потом разберетесь.
Выбор архитектуры — это всегда компромисс. Нет идеального решения, которое подойдет всем. Монолиты хороши для быстрого старта, микросервисы — для больших распределенных систем, а модульные монолиты — для тех, кто хочет организованный код без операционной сложности микросервисов.
На своем примере могу сказать: какую бы архитектуру вы ни выбрали, важнее всего последовательность и дисциплина в её реализации. И небольшая доза фатализма не помешает — все равно через пару лет вы будете всё переписывать под новые требования.
А если заказчик спросит, какую архитектуру лучше выбрать, всегда можно ответить классическим аналитическим «зависит от ваших потребностей» и провести трехчасовой воркшоп по выявлению этих самых потребностей. К концу воркшопа обычно уже никто не помнит, с чего началось обсуждение, и вы можете спокойно предложить любой вариант.
И помните: какой бы ни была архитектура вашей системы, в конечном итоге всё упирается в людей, которые её разрабатывают и поддерживают. Даже самая элегантная архитектура может превратиться в чудовище в неумелых руках. И наоборот, даже с монолитом можно жить счастливо, если ваша команда знает, что делает и умеет писать тесты.
PS: Автор данной статьи не несет ответственности за архитектурные решения, принятые под влиянием прочитанного материала.