Найти тему
REUNICO

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

Оглавление

В этом году нашей компании исполнилось 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

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

Существует два подхода к масштабированию монолитных приложений на 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-движок отдельно бизнес-логики микросервиса. Однако, и здесь возможны варианты, речь о которых пойдет ниже.
embedded engine
embedded engine

Remote Engine

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

  • Запускают процессы;
  • Отправляют сообщения;
  • Получают от BPM-системы информацию о задачах, которые должны быть выполнены;
  • Сообщают результат выполнения задачи (успешно или сбой).

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

  • Асинхронное выполнение задач (так называемые внешние задачи, External Task).
  • Возможность масштабировать микросервисы отдельно от Camunda.
  • Менее трудозатратен переход на Camunda 8 (в ней используется аналогичный подход).
remote engine
remote engine

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

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

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