В этом посте начну обзор книги “Микросервисы. Паттерны разработки и рефакторинга” Криса Ричардсона. Рассмотрим, чем микросервисная архитектура отличается от монолитной, их преимущества и недостатки.
Что такое микросервис?
Это автономный, независимо развертываемый программный компонент, который реализует некоторые полезные функции. У него есть 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 перегружается из-за объемной кодовой базы и замедляется, приложение долго собирается и запускается;
- Сложное и долгое развертывание: т.к. изменения затрагиваю всю кодовую базу и изменения в одном месте могут вылиться в неочевидные ошибки в другом, требуется проходить полный цикл тестов, и даже требуется ручное тестирование;
- Зависимость от устаревающих технологий: приходится работать с решениями, выбранными на старте проекта;
Преимущества микросервисной архитектуры
- Возможность непрерывной доставки и развертывания крупных и сложных приложений;
- Сервисы получаются небольшими и простыми в обслуживании;
- Независимое развертывание и разработка сервисов;
- Автономность команд разработчиков;
- Возможность экспериментировать и использовать новые технологии;
Недостатки микросервисной архитектуры
- Сложно подобрать подходящий набор сервисов;
- Разработка функций, которые затрагивают несколько сервисов, нетривиальна, и требует тщательного согласования и координации команд;
- Распределенные системы более сложны в разработке, тестировании и развертывании;
- Сложность организации межсервисного взаимодействия.