10.09.24

Эволюция архитектуры ИТ-решений

10 мин · Обучающие
Эволюция архитектуры ИТ-решений

Всем привет!


На связи Мстислав, компания Реюнико. В 2024 году нам исполнилось 10 лет! По причине этого знаменательного события мы решили выпустить цикл статей об изменениях, произошедших за последнее десятилетие в ИТ и управлении бизнес-процессами. Открывает цикл статья, посвященная тому, как менялась архитектура ИТ-решений.


Как выглядела архитектура типичного корпоративного приложения 10 лет назад?


Фундаментом (или даже правильнее сказать – домом) приложения является сервер приложений (application server), например JBoss AS, IBM Websphere, Oracle Weblogic. Из свободно распространяемых серверов приложений наибольшей популярностью сохраняет Apache Tomcat, появившившийся аж в 1999 году.


Сервер приложений выступает в роли контейнера для веб-приложений на Java (в формате .war или .jar), обеспечивая среду для работы сервлетов, JSP и других технологий Java EE.


Преобладает монолитная архитектура, имеющая характерные черты:


  • Единое приложение — все функциональные компоненты (например «Платежи», «Доставка», «Оформление заказа» находятся в одном приложении.

  • Отсутствие модульности — все части приложения зависят друг от друга, их сложно раздельно развернуть или заменить.

  • Централизованное управление — управление кодом, релизами и версионированием осуществляется через единый центр.

  • Если говорить о Java-приложениях — все компоненты взаимодействуют через общую JVM, используя сервер приложения (например, Tomcat) для обработки HTTP-запросов и предоставления сервлетов.

Монолитная архитектура

(Тот самый черный ящик от вендора, он же черный монолит)


Есть возможность повторного использования – разные приложения могут использовать общие компоненты (библиотеки) развернутые на уровне сервера приложений. Так, например, Camunda 7 может быть развернута как библиотека Tomcat, которую могут использовать несколько разных процессных приложений (так называемый Shared Engine).


Монолитное приложение

(а это - монолит на Tomcat)


Масштабирование монолита


Существует два подхода к масштабированию монолитных приложений на Tomcat.


Вертикальное масштабирование


  • Простое увеличение аппаратных ресурсов (памяти, CPU) на сервере, где развернут Tomcat.

  • Настройка JVM-параметров в конфигурации Tomcat, таких как Xms, Xmx, для оптимизации использования памяти.


Горизонтальное масштабирование


  • Развертывание нескольких экземпляров Tomcat на разных серверах.

  • Использование Балансировщика нагрузки (например, Nginx, HAProxy, Apache HTTP Server) для распределения трафика между несколькими экземплярами Tomcat.

  • Плюсы: приложение может обрабатывать больше запросов за счет распределения нагрузки.

  • Минусы: нужно учитывать синхронизацию данных между экземплярами, возможные конфликты с сессиями пользователя, если они не сохранены в общей базе данных или в другом общем хранилище (например, Redis). Иногда необходимо подкрутить настройки балансировщика.


Масштабирование монолитного приложения

(масштабирование монолита)


Какие подводные камни имела монолитная архитектура?


  • Масштабирование монолита приводит к избыточному потреблению ресурсов, поскольку необходимо масштабировать все приложение целиком, даже если требуется больше ресурсов только для одной его части (например, для обработки платажей).

  • Сложность поддержки и обновлений — изменение одной части приложения может потребовать его полной пересборки и развертывания, что увеличивает риск ошибок.

  • Медленная доставка изменений — в монолите часто изменения доставляются медленнее, так как они могут затрагивать множество модулей, что требует полной проверки и регрессионного тестирования.

  • Ограниченная гибкость — трудно применять разные технологии или инструменты для разных частей приложения.


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


Рост нагрузки, развитие средств контейнеризации, инструментов быстрого развертывания и управления конфигурациями приложений привели к появлению концепции микросервисной архитектуры (MSA).


Микросервисная архитектура — это подход к проектированию программного обеспечения, при котором приложение разделяется на небольшие, независимые сервисы, каждый из которых выполняет конкретную функцию. Эти микросервисы работают вместе, взаимодействуя через четко определенные API, и могут быть развернуты, масштабированы и обновлены независимо друг от друга.


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


  • Гибкость в разработке. Команды могут разрабатывать микросервисы независимо друг от друга. Это увеличивает скорость разработки и внедрения новых функций. Легко интегрировать разные технологии, поскольку каждый микросервис может быть написан на разных языках программирования и использовать различные базы данных.

  • Независимое развертывание. Можно обновлять и разворачивать микросервисы независимо, не влияя на работу других частей системы. Это особенно полезно для сложных систем, где внесение изменений в монолитное приложение может быть затруднено.

  • Масштабируемость. Микросервисы позволяют более эффективно управлять ресурсами. Вы можете масштабировать только те сервисы, которые нуждаются в большем количестве ресурсов.

  • Устойчивость к сбоям. Если один микросервис выходит из строя, остальные сервисы продолжают работать. Это повышает отказоустойчивость системы.


Подводные камни и вызовы


  • Усложнение архитектуры. Микросервисная архитектура более сложна в плане управления по сравнению с монолитной архитектурой. Необходимо отслеживать взаимодействие между множеством сервисов, их состояние и связи.

  • Повышенные требования к инфраструктуре. Для поддержки микросервисов необходимы сложные системы мониторинга, логирования, управления конфигурацией и балансировки нагрузки. Оркестрация контейнеров с помощью инструментов, таких как Kubernetes или Docker Swarm, часто становится необходимостью.

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

  • Тестирование. Тестирование микросервисов может быть сложным, так как необходимо проверять как каждый сервис отдельно, так и взаимодействие между ними.

  • Целостность бизнес-транзакций. Бизнес-транзакция в монолитном приложении часто эквивалентна технической (ACID) транзакции. Откат такой бизнес-транзакции (например, отмена бронирования авиабилетов) легко может быть выполнен путем отката транзакции (rollback) в СУБД. Однако, в случае использования микросервисной архитектуры приходится идти на дополнительные сложности, например использовать так называемый SAGA-паттерн или BPM-систему.

  • Безопасность. Множество микросервисов увеличивает поверхность для атак, что требует продуманной системы аутентификации и авторизации, часто через механизмы OAuth2, OpenID Connect или использования API Gateway.


Повсеместное внедрение микросервисной архитектуры оказало влияние и на способы использования в ней Camunda Platform.


Embedded Engine


В этом случае движок Camunda встраивается в микросервис, представляющий собой Java-приложение. Сквозной (end-to-end) процесс декомпозируется на диаграмму коллаборации (collaboration diagram), состоящую из отдельных процессов-пулов,  взаимодействующих друг с другом посредством брокера сообщений, gRPC или REST API. Границы такого процесса будут эквивалентны контексту микросервиса. Взаимодействие сервисом представляет собой хореографию. Каждый сервис знает, с кем он должен взаимодействовать, осведомлен о входах и выходах процесса, а также выполняемой работе. Взаимодействие между Camunda и сервисным слоем происходит посредством Java API.


Обработка заказа

(диаграмма коллаборации отлично накладывается на микросервисную архитектуру)


Преимущества


  • Общий жизненный цикл BPM-движка и приложения. Изменения как процесса, так и сервисов можно выкатывать общим релизом или патчем.

  • Устраняется эффект «шумных соседей». Изменения моделей процессов и настроек Camunda, выполненные один подразделением, не будут затрагивать сервисы других подразделений.


Недостатки


  • Способ подходит, в основном, только для разработки на Java / Spring Boot. Впрочем, утилитарные сервисы (ordinary services), вызываемые в процессе в виде задач, могут быть разработаны с использованием любого техстека.

  • Нет возможности масштабировать BPM-движок отдельно бизнес-логики микросервиса. Однако, и здесь возможны варианты, речь о которых пойдет ниже.

Camunda встраивается в микросервис


(embedded engine)

Remote Engine


Camunda Platform поднимается в виде отдельной службы, представляющего собой оркестратор микросервисов. Микросервисы взаимодействуют с Camunda через REST API:


  • Запускают процессы;

  • Отправляют сообщения;

  • Получают от BPM-системы информацию о задачах, которые должны быть выполнены;

  • Сообщают результат выполнения задачи (успешно или сбой).


Преимущества


  • Асинхронное выполнение задач (так называемые внешние задачи, External Task).

  • Возможность масштабировать микросервисы отдельно от Camunda.

  • Менее трудозатратен переход на Camunda 8 (в ней используется аналогичный подход).

Camunda разворачивается отдельно от микросервисов

(remote engine)

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


Иногда наиболее эффективным решением оказывается комбинированная архитектура, где бизнес-сервисы реализованы как Embedded Engine, а повторно используемая рутина вынесена во внешние задачи.


А какую архитектуру используете вы? Поделитесь своими идеями или задайте вопросы на нашем форуме.