Микросервисная vs. Монолитная архитектура

Дарья Матвеева · February 25, 2024

В этом посте начну обзор книги “Микросервисы. Паттерны разработки и рефакторинга” Криса Ричардсона. Рассмотрим, чем микросервисная архитектура отличается от монолитной, их преимущества и недостатки.

Что такое микросервис?

Это автономный, независимо развертываемый программный компонент, который реализует некоторые полезные функции. У него есть API, через которые сервис предоставляет доступ к своим функциям. API инкапсулирует внутреннюю реализацию сервиса. Это значит, что другие сервисы, в частности, не имеют доступа к БД другого микросервиса.

В случае монолита аналогом сервиса может считаться модуль. В этом случае взаимодействие между модулями происходит с использованием методов языка программирования. А микросервисы взаимодействиют используя механизмы межпроцессного взаимодействия, например на основе запросов/ответов (REST, gRBC …) или же aсинхронные механизмы коммуникации.

Какой может быть архитектура приложения?

Архитектура приложения - это декомпозиция его на части (элементы) и связи между ними. Автор говорит, что приложение можно рассматривать и описывать с разных сторон, как например здание можно описать с точки зрения его конструкции, устройства водопровода, электропроводки и т.д.

Такое описание с разных точек зрения дает модель представлений “4 + 1”. Каждое из 4-х представлений описывает определенный аспект архитектуры и состоит из набора программных элементов и связей между ними. Сюда добавляются (+1) сценарии взаимодействия компонентов внутри каждого отдельного представления.

  • Логическое представление (Logical view) – это программные элементы, которые пишут разработчики. Например, в ООП языках это классы и пакеты. А связи между ними - это наследование, композиция, зависимости.

  • Представление реализации (Development view) – это результат работы системы сборки. Состоит из модулей, содержащих упакованный код, и компонентов, состоящих из нескольких модулей. В Java модуль - это обычно jar файл, а компонент - это либо war, либо исполняемый jar файл.

  • Представление процесса (Process view) – рассматривает процессы во время выполнения программы и связи между ними - межпроцессное взаимодействие.

  • Развертывание (Physical view) - рассматривает, как процессы распределяются по физическим устройствам (серверам), как по сети проходят запросы между компонентами.

Сценарии описывают взаимодействие компонентов внутри одного представления.

С точки зрения представления реализации монолитная архитектура структурирует приложение в виде единого компонента - исполняемого war или jar файла.

А микросервисная в виде набора компонентов – исполняемых фалов. Компоненты представляют собой отдельные сервисы, которые взаимодействуют между собой по некоторым коммуникационным протоколам.

При этом на остальные представления не накладывается ограничений.

Функциональные и нефункциональные требования

Требования к архитектуре обычно делятся на 2 вида.

  • Функциональные, описывающие сценарии использования.
  • Нефункциональные – связанные с качеством обслуживания. Это может быть например, простота в тестировании, развертывании.

Архитектура выходит на первый план при обсуждении нефункциональных требований, т.к. функциональные можно реализовать в любой архитектуре.

Микросервисная архитектура часто позволяет удовлетворить нефункциональные требования для крупных и сложных приложений.

Преимущества монолитной архитектуры

  • Простота разработки: IDE заточена на создание единого приложения;
  • Легкость внесения радикальных изменений: т.к. все изменения в рамках одного приложения, то меньше согласований;
  • Простота тестирования: можно легко писать сквозные тесты для разных сценариев;
  • Простота развертывания: достаточно скопировать 1 исполняемый файл на сервер;
  • Легкость масштабирования: можно запустить несколько экземпляров приложения за балансировщиком нагрузки;

Но при развитии приложения и увеличении кодовой базы возникают проблемы.

Недостатки монолитной архитектуры

  • Высокий порог входа: зависимости между модулями становится сложно понимать;
  • Медленная разработка: IDE перегружается из-за объемной кодовой базы и замедляется, приложение долго собирается и запускается;
  • Сложное и долгое развертывание: т.к. изменения затрагиваю всю кодовую базу и изменения в одном месте могут вылиться в неочевидные ошибки в другом, требуется проходить полный цикл тестов, и даже требуется ручное тестирование;
  • Зависимость от устаревающих технологий: приходится работать с решениями, выбранными на старте проекта;

Преимущества микросервисной архитектуры

  • Возможность непрерывной доставки и развертывания крупных и сложных приложений;
  • Сервисы получаются небольшими и простыми в обслуживании;
  • Независимое развертывание и разработка сервисов;
  • Автономность команд разработчиков;
  • Возможность экспериментировать и использовать новые технологии;

Недостатки микросервисной архитектуры

  • Сложно подобрать подходящий набор сервисов;
  • Разработка функций, которые затрагивают несколько сервисов, нетривиальна, и требует тщательного согласования и координации команд;
  • Распределенные системы более сложны в разработке, тестировании и развертывании;
  • Сложность организации межсервисного взаимодействия.

VK, Telegram