Фреймворки разработки для приложений на основе микросервисов: оценка и сравнение

Хай Динь-Туан, Мария Мора-Мартинес, Феликс Бейерле, Сандро Родригес Гарсон
Технический университет Берлина
Эрнст-Ройтер-Плац 7, 10587 Берлин
Национальный институт информатики
hai.dinhtuan@tu-berlin.de, m.moramartinez@tu-berlin.de, beierle@tu-berlin.de, sandro.rodriguezgarzon@tu-berlin.de

АННОТАЦИЯ

Микросервисный архитектурный стиль недавно привлек большое внимание как академических кругов, так и промышленности как новый способ проектирования, разработки и развертывания облачно-нативных приложений. Эта концепция поощряет декомпозицию монолита на множество независимо развертываемых единиц. Типичное приложение на основе микросервисов формируется из двух типов сервисов: функциональные сервисы, которые предоставляют основную бизнес-логику, и инфраструктурные сервисы, которые предоставляют основные функциональные возможности для экосистемы микросервисов. Чтобы повысить производительность разработчиков, было разработано множество программных фреймворков для предоставления этих повторно используемых инфраструктурных сервисов, позволяющих программистам сосредоточиться на реализации микросервисов произвольными способами. В этой работе мы использовали четыре фреймворка с открытым исходным кодом для разработки облачного приложения, чтобы сравнить и оценить их удобство использования и практичность. Хотя все выбранные фреймворки в целом продвигают асинхронный дизайн микросервисов, существуют различия в способах реализации сервисов каждым из них. Это приводит к проблемам совместимости, таким как соглашение об именовании топиков сообщений. Кроме того, ключевым выводом являются долгое время запуска сервисов на основе JVM, что может снизить устойчивость и переносимость приложения. Некоторые другие преимущества проистекают непосредственно из языка программирования, такие как способность Go генерировать нативные исполняемые файлы, что приводит к очень маленьким и компактным образам Docker (до 78% меньше по сравнению с другими языками).

1. ВВЕДЕНИЕ

Микросервисный архитектурный стиль возник из архитектурных шаблонов Сервис-ориентированной архитектуры и Предметно-ориентированного проектирования с сильным акцентом на практики DevOps [15]. Он не только был успешно принят в компаниях с многомиллионными пользователями, таких как Netflix или Amazon, но и получил значительное внимание со стороны академических кругов как надежный и масштабируемый метод построения облачных приложений. Короче говоря, микросервисная архитектура пропагандирует новый дизайн программного обеспечения, в котором приложение структурировано в сервисы. Эти сервисы независимо разрабатываются, обновляются и развертываются, что значительно улучшает гибкость приложения. Аналогично, общая масштабируемость и отказоустойчивость приложения улучшаются. Однако эти преимущества также имеют свою цену. Приложения становятся более сложными, а задержки увеличиваются, потому что канал связи более подвержен сетевым задержкам.

Чтобы уменьшить бремя, создаваемое сложностью распределенных систем, было разработано несколько фреймворков специально для микросервисов. Они предоставляют шаблонный код и абстракции, чтобы позволить разработчикам сосредоточиться на бизнес-логике. Исследуя варианты реализации для примера приложения, эта статья предлагает три критерия для оценки и сравнения фреймворков. Для функциональных возможностей мы сравниваем фреймворки по трем основным категориям: зрелость, поддержка разработки и встроенные функции. Для шаблонов проектирования мы категоризировали поддерживаемые на шесть групп. Наконец, для производительности мы полагались на два основных критерия: сквозная производительность задержки и потребление ресурсов. Таким образом, эта статья предоставляет троякий вклад:

  1. Обзор различных подходов к реализации микросервисов, который демонстрируется в четырех выбранных микросервисных фреймворках.
  2. Модель сравнения для фреймворков микросервисов, основанная на трех основных критериях: функциональные возможности, шаблоны проектирования и производительность.
  3. Последствия принятия фреймворка при разработке микросервисов.

В остальной части этой статьи Раздел 2 дает краткий отчет об оценках и сравнениях, проведенных до сих пор для микросервисов. Затем мы представляем мотивирующий пример использования и архитектуру прототипа системы взимания платы в Разделе 3. Раздел 5 представляет сравнение по характеристикам, а Раздел 6 показывает практические результаты производительности. Мы обсуждаем результаты в Разделе 7, делаем общий вывод в Разделе 8 и перечисляем будущие направления исследований в Разделе 9.

3. МОТИВАЦИОННЫЙ ПРИМЕР ИСПОЛЬЗОВАНИЯ

Одной из самых больших проблем в городских районах является снижение качества воздуха, которое вызывает \(4.2\) миллиона преждевременных смертей каждый год, согласно недавнему отчету Всемирной организации здравоохранения (ВОЗ) [20]. В том же отчете мобильность человека была определена как основной источник загрязнения наружного воздуха, включая сжигание ископаемого топлива автомобилями.

Во многих странах политики ввели различные регулирования для решения этих проблем, одним из них является внедрение платы за загрязнение. Однако текущие схемы взимания платы взимают фиксированные сборы на основе статических критериев, таких как тип транспортного средства или зона взимания платы [26]. В этой работе, вдохновленные [10], мы предлагаем новую детализированную систему для расчета платы за проезд пропорционально уровню загрязнения каждой области. Это означает, что чем более загрязнена область, тем выше плата за пройденный километр применяется для всех транспортных средств в этой области. Одним очевидным преимуществом этого подхода является то, что эта система позволяет динамическую ставку платы на основе уровня загрязнения воздуха в реальном времени. Кроме того, это очень масштабируемо, поскольку она использует только данные о местоположении транспортного средства в короткие интервалы для расчета платы за проезд. Справедливость этой системы может быть дополнительно улучшена добавлением информации о модели транспортного средства и скорости (оцененной из данных о местоположении).

Гипотетическая система взимания платы принимает событийно-ориентированную микросервисную архитектуру, в которой каждый микросервис отвечает за конкретную задачу, и данные обмениваются как JSON через брокер сообщений, используя асинхронный шаблон обмена сообщениями издатель-подписчик.

Рис. 1 иллюстрирует архитектуру, в которой стрелки между микросервисами - это не прямое общение, а скорее косвенное общение через брокер сообщений. Конвейер обработки объяснен подробно ниже:

Рисунок 1: Обзор архитектуры предлагаемой системы взимания платы с
          учетом загрязнения воздуха.

Рисунок 1: Обзор архитектуры предлагаемой системы взимания платы с учетом загрязнения воздуха.

4. ФРЕЙМВОРКИ

Существует большое количество фреймворков для разных языков программирования. Для реализации системы взимания платы мы выбрали четыре различных фреймворка микросервисов: Go Micro (Go), Molecular (JavaScript с Node.js), Lagom (Scala) и Spring Boot/Spring Cloud (Java). Они выбраны, чтобы отразить разнообразие инструментов, которые могут быть использованы для разработки микросервисов. Что касается языков программирования, Java считается «старым» языком, в то время как Scala и Go были представлены в последнее десятилетие, и Node.js - это новая среда выполнения для JavaScript. С точки зрения философии дизайна фреймворка, хотя Spring Boot широко используется для микросервисов, он не разработан специально для таких приложений, как другие три. Каждый фреймворк предоставляет различный подход к построению приложений на основе микросервисов. В этом разделе мы кратко обсуждаем основные различия.

Go Micro предоставляет абстракцию для разработки распределенных систем с использованием Удаленного вызова процедур (RPC) и событийно-ориентированной коммуникации, написанную на Go. Этот опинионизированный фреймворк предоставляется как набор подключаемых строительных блоков, которые могут быть включены или исключены в проекте в зависимости от специфических требований приложения. Этот дизайн снижает сложность в разработке. Они охватывают широкий спектр функциональностей, от синхронной/асинхронной передачи сообщений, кодирования сообщений, обнаружения сервисов, до динамической конфигурации. Чтобы определить микросервис с Go Micro, фреймворк поощряет разработчиков сначала определить интерфейсы (по умолчанию через ProtoBuf), а затем реализовать их. После этого сервис может быть инициализирован и зарегистрирован во встроенном реестре сервисов.

Lagom - это еще один опинионизированный микросервисный фреймворк для построения реактивных микросервисов на Scala или Java. Разработанный и поддерживаемый той же компанией, что стоит за Akka и Play Framework, Lagom построен для легкой интеграции в эти две технологии. Lagom поддерживает и поощряет использование Поиска источников событий (Event sourcing) и Разделения ответственности команд и запросов (CQRS) для сохранения данных. Lagom рекомендует разработчикам разделять интерфейс сервиса и реализацию сервиса, которые организованы как подпроекты в пределах одной сборки. В то время как первый содержит описания интерфейсов вместе с моделями данных, второй реализует логику сервиса.

Molecular - это микросервисный фреймворк для JavaScript, использующий среду выполнения Node.js, построенную на движке V8 JavaScript от Chrome. Основная философия дизайна этого фреймворка - создание приложений с низкой задержкой, управляемых событиями. Molecular также предоставляет подключаемые модули для различных функций, таких как шлюзы, база данных, сериализация и т.д. Фреймворк состоит из трех основных компонентов: транспортер, сервис и брокер сервисов. В то время как сервис определяет общую структуру для каждого микросервиса, транспортер - это абстракция для шины связи, а брокер сервисов связывает сервис с транспортером.

Spring Boot & Spring Cloud - это два проекта из экосистемы Spring. В то время как Spring Boot - это опинионизированный способ построения автономных Spring-приложений, Spring Cloud предоставляет набор инструментов для быстрого построения нескольких общих шаблонов в распределенных системах, таких как обнаружение сервисов, управление конфигурацией и т.д. Это означает, что Spring Boot не разработан специально для разработки микросервисов, а скорее как среда разработки полного стека. Spring Boot должен полагаться на Spring Cloud для возможностей, специфичных для микросервисов.

5. СРАВНЕНИЕ ХАРАКТЕРИСТИК

В этом разделе мы предоставляем обширную оценку этих фреймворков относительно 2 основных критериев: функциональные возможности и шаблоны проектирования. Для первого мы дополнительно подкатегоризируем его на (1) Зрелость, (2) Поддержка разработки микросервисов и (3) Встроенные функции. Все эти детали будут суммированы в Таблице 1 и Таблице 2. Обратите внимание, что «N/A» не обязательно означает, что фреймворку не хватает определенной функции, а скорее, что функция требует внешних библиотек, которые еще не были официально интегрированы во фреймворк.

5.1 Основные функции и философия дизайна

Все четыре микросервисных фреймворка сосредоточены на предоставлении инфраструктурных сервисов для приложений на основе микросервисов. Фактически, разделение между инфраструктурными сервисами и функциональными сервисами хорошо обсуждалось в литературе [5]. В то время как инфраструктурные сервисы предоставляют основные возможности, такие как реестр сервисов или обнаружение сервисов, функциональные сервисы - это те, которые предоставляют фактическую бизнес-логику.

Как наблюдается в четырех реализациях, есть два основных подхода от разных фреймворков: они могут либо реализовать свои собственные сервисы, либо предоставить интеграцию с существующими решениями. Кроме того, как проекты с открытым исходным кодом, помимо официального кода, они могут предоставлять сообщественно-поддерживаемые плагины и модули, такие как в Go Micro и Molecular.

5.2 Зрелость

Чтобы количественно оценить зрелость фреймворка с открытым исходным кодом, мы смотрим на цикл выпуска и метрики с сайтов открытого исходного кода для хостинга кода, таких как GitHub, как использовалось в предыдущих исследованиях [6, 18].

Учитывая, что Spring Boot был первоначально выпущен в 2014 году, в то время как первый выпуск Lagom был в 2016 году, а Go Micro и Molecular - в 2017 году, Spring Boot стал одним из самых зрелых фреймворков. Это также объясняет, как количество выпусков от Spring превосходит другие в два раза, как видно в Таблице 1. Однако, поскольку Spring Boot также является популярным фреймворком для построения общих Java-приложений, это может не полностью отражать зрелость Spring в разработке микросервисов конкретно.

5.3 Поддержка разработки микросервисов

Учитывая разницу в зрелости среди выбранных фреймворков, можно ожидать разных уровней поддержки и кривых обучения. Действительно, документация Spring Boot очень обширна по сравнению с другими. С огромным сообществом и долгим существованием на рынке легко найти поддержку от сообществ разработчиков, таких как StackOverflow. Кроме того, Spring и Lagom поддерживаются Pivotal и Lightbend соответственно, поэтому они могут предложить коммерческую поддержку для крупных организаций, в то время как Molecular и Go Micro должны полагаться на сообщественную поддержку. Инструменты сборки и решения управления зависимостями играют важную роль для значительного улучшения производительности. Шаблонные коды для новых микросервисов могут быть быстро сгенерированы по определенным шаблонам, однако каждый фреймворк поддерживает разный уровень настройки. Например, Lagom и Molecular позволяют только настроить имя проекта и имя сервиса, в то время как другие два позволяют указывать пакеты зависимостей. Кроме того, функции, такие как горячая перезагрузка или интерактивная консоль разработки, могут дополнительно сократить циклы разработки, поскольку они помогают разработчикам немедленно видеть эффекты нового кода во время выполнения.

5.4 Шаблоны проектирования

Для достижения надежности в микросервисах есть определенные рекомендации, которым нужно следовать, такие как минимизация зависимостей сервисов или разделение хранилища данных [21]. Эти нефункциональные свойства материализуются в разных шаблонах проектирования. Чтобы понять, как философия дизайна каждого выбранного фреймворка отличается друг от друга, мы кратко обсуждаем их в этом разделе и предоставляем сводку в Таблице 2.

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

Другим шаблоном проектирования, пропагандируемым всеми фреймворками, является шаблон проектирования База данных на сервис. Дизайн микросервисов помогает

разделению сервисов, так как они могут разрабатываться, развертываться и обновляться без поломки других сервисов. Однако данные могут создавать скрытые зависимости между сервисами. Поэтому каждый микросервис должен управлять своими собственными данными, и никакой сервис не может модифицировать данные, принадлежащие другому сервису. В противоположность этому, общие базы данных между несколькими сервисами не поощряются никаким фреймворком. Более продвинутый шаблон, такой как Разделение ответственности команд и запросов с Поиском источников событий, даже является частью философии фреймворка, как в случае с Lagom.

В среде с множеством сервисов, независимо развернутых, крайне важно для операторов иметь обзор приложения и понимание основных операций [3]. Поэтому все четыре фреймворка предоставляют обширную интеграцию с различными инструментами логирования. Однако, когда дело доходит до сбора метрик, в то время как Molecular имеет встроенный модуль, собирающий и публикующий метрики в различные выходы, Spring Boot и Go Micro предоставляют сборщик метрик как подключаемый модуль; Lagom должен полагаться на облачную платформу Lightbend для этих возможностей. Это потому, что Lagom был разработан для упрощения разработки и развертывания приложений микросервисов на текущем предложении Lightbend в облачной платформе.

Аналогично, техника, используемая для мониторинга и анализа распределенных систем, называемая Распределенная трассировка (Distributed Tracing), также поддерживается всеми фреймворками. В этой технике, когда запрос проходит через систему, добавляется уникальный идентификатор, позволяющий детали о пути, времени, проведенном в каждом сервисе, быть центрально захваченными и визуализированными. Хотя ни один фреймворк не предоставляет свою собственную реализацию сервиса мониторинга, поддерживающего Распределенную трассировку, Spring Boot, Molecular и Go Micro полностью интегрированы с внешними решениями, такими как Prometheus. В противоположность этому, микросервисы Lagom снова должны полагаться на платформу Lightbend.

С недавним ростом контейнерных облачных платформ, Docker и оркестрационные платформы на основе Docker, такие как Kubernetes, Mesosphere DC/OS, OpenShift и т.д., стали де-факто стандартом. Все фреймворки имеют поддержку для развертывания Docker, кроме поддержки Molecular для Kubernetes все еще отсутствует. И Spring Boot, и Lagom могут строить исполняемые файлы, которые могут быть развернуты на Heroku, Azure и т.д.

Что касается шаблонов коммуникации между микросервисами, все фреймворки поощряют использование асинхронной передачи сообщений как основного способа обмена информацией. Асинхронная передача сообщений может разделить сервисы, минимизируя зависимости и улучшая отказоустойчивость приложения в целом [22]. Фактически, способность работать асинхронно - это один из критериев дизайна, чтобы получить максимальную отдачу от микросервисного архитектурного стиля [9]. В то время как большинство широко используемых протоколов, таких как AMQP, MQTT, полностью поддерживаются всеми, каждый фреймворк реализует канал связи по-разному: Spring, Lagom и Go Micro предоставляют разные модули интеграции для брокеров сообщений, в то время как Molecular различает два типа коммуникации. Локальные сервисы используют внутрипамятную локальную шину для обмена сообщениями. Удаленные сервисы полагаются на слой абстракции, называемый Транспортер (Transporter), который может доставлять события, запросы и ответы. По умолчанию NATS используется как брокер, однако другие реализации не могут быть добавлены напрямую, потому что Molecular автоматически добавляет префиксы к топикам сообщений.

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

Таблица 1. Характеристики фреймворков микросервисов.

Spring Lagom Moleculer Go Micro
Зрелость Дата первого релиза 10 июля 2014 3 марта 2016 16 февраля 2017 6 декабря 2017
Релизы 146 76 86 70
Коммиты 25357 2397 3222 2700
Watch 3348 165 123 452
Star 45626 2370 3322 11748
Контрибьюторы 656 126 65 77
Поддержка разработки Документация Очень обширная Обширная Менее обширная Ограниченная
Пример кода Да Да Да Да
Поддерживаемые языки Java, Kotlin, Groovy, Beanshell Java, Scala Javascript/Node.js Go
Теги StackOverflow 162688 296 38 29
Платформа чата Gitter Gitter Gitter Slack
Форум Да Да Да Да
GitHub Да Да Нет Нет
Курсы обучения Да Да Нет Нет
Среда разработки Инструмент сборки & Управление зависимостями Maven (по умолчанию), Gradle, Ant sbt По умолчанию npm По умолчанию Go Build
Генератор шаблонов Spring Initialzr (веб-базированный) Lagom Tech Hub Project Starter (веб-базированный) moleculer-cli команда micro new команда
Горячая перезагрузка Да, но не по умолчанию Да, поддерживается по умолчанию с sbt Да, включена по умолчанию N/A
Интерактивная консоль разработки N/A sbt development console, только для целей разработки REPL консоль: список узлов, сервисов, действий, событий, переменных окружения и т.д. Интерактивный Micro CLI, для управления сервисами
Другие функции API Gateway Да Да Да Да
Обнаружение сервисов Да Да Да Да
Реестр сервисов Да Да Да Да
Балансировка нагрузки Spring Cloud Load Balancer Полагается на основную Akka Балансировка нагрузки на стороне сервера по умолчанию proxy пакет
Сериализация JSON от Jackson JSON (по умолчанию), ProtoBuf, Apache Avro, Kryo JSON (по умолчанию), Avro, MsgPack, Notepack, ProtoBuf, Thrift, и пользовательские модули JSON или ProtoBuf
Интеграция со Slack N/A N/A N/A bot пакет
Интерактивный CLI Spring Boot CLI sbt moleculer REPL Micro CLI пакет
Веб-панель управления N/A N/A N/A web пакет

Таблица 2. Шаблоны проектирования фреймворков микросервисов.

Spring Lagom Moleculer Go Micro
API Gateway Spring Cloud Gateway, построен на основе Spring MVC, Netty Встроенный шлюз по умолчанию на основе Akka HTTP moleculer-web для маршрутизации запросов Go API библиотеки для перевода протоколов и маршрутизации запросов
База данных на сервис Поддерживается Cassandra, MySQL, PostgreSQL, Oracle, Couchbase, Microsoft SQL, H2 MongoDB, MySQL, PostgreSQL, SQLite, MSSQL. По умолчанию CRUD действия Только предоставляет интерфейс Store для дополнительного хранилища в будущем
Общая база данных Поддерживается Не поощряется Не поощряется N/A
CQRS/Event Sourcing Поддерживается По умолчанию N/A N/A
Агрегация логов Logback (по умолчанию), Java Util Logging, Log4J2 SLF4J на основе Logback (по умолчанию), Log4J2 Вывод консоли, Pino, Bunyan, Winston, Log4js, Datadog Logrus, Zap, Zerolog
Метрики производительности Prometheus, Datadog, Netflix Atlas Предоставляется платформой Lightbend Prometheus, StatsD, Datadog Prometheus
Распределенная трассировка Поддерживается с Spring Cloud Sleuth Предоставляется Lightbend, который поддерживает OpenTracing Встроенный модуль трассировки работает с Zipkin, Jaeger, Datadog Amazon AWS X-Ray, UUID плагин для ручной трассировки сообщений
Проверка здоровья Поддерживается с Spring Actuator N/A Встроенная Реализация Sidecar через RPC
Внешняя конфигурация Spring Cloud Netflix для клиентской и серверной стороны, Netflix Archaius N/A Внешние файлы конфигурации могут быть загружены через moleculer-runner Поддерживается через Go Config
Реестр сервисов Netflix Eureka. Также Kubernetes, Consul, Apache Zookeeper, Alibaba Nacos Предоставляется по умолчанию Встроенный реестр сервисов Встроенный, может быть доступен через Веб-панель управления
Обнаружение сервисов на стороне клиента Клиентская балансировка нагрузки поддерживается с Ribbon Предоставляется в Serviced_ocator N/A mdns, etcd
Обнаружение сервисов на стороне сервера N/A Поддерживается По умолчанию mdns, etcd
Платформа развертывания Docker, Kubernetes, Cloud Foundry, Azure, Heroku, Amazon AWS, OpenShift, Boxfuse Docker, Kubernetes, OpenShift, MesosphereDC/OS Docker/Docker Compose, Kubernetes в разработке Локально, Docker, Kubernetes
Синхронная передача сообщений Поддерживается Поддерживается Поддерживается Поддерживается
Асинхронная передача сообщений RabbitMQ, Apache Kafka, Amazon Kinesis, Google PubSub Message Broker API для Kafka Предпочтительно: NATS, Kafka, Redis, MQTT, AMQP PubSub предпочтителен. Встроенный сервер NATS по умолчанию
Удаленный вызов процедур RMI, Spring’s HTTP Invoker, Hessian, Burlap Akka gRPC библиотека HTTP/JSON RPC реализован по умолчанию Поддерживает gRPC
Автоматический выключатель Поддерживается с Netflix Hystrix Используется для всех вызовов сервисов по умолчанию Встроенный, на основе порога Поддерживаются плагины
Повтор Spring-retry, аннотация Retryable N/A Экспоненциальный повтор с задержкой Повторная отправка запросов на другой узел
Таймаут Для HTTP компонентов Автоматический выключатель: время вызова и сброса Установка значений таймаута для запросов N/A

6. ОЦЕНКА ПРОИЗВОДИТЕЛЬНОСТИ

6.1 Тестовая установка

Мы реализовали конвейер, как описано в разделе 3, с каждым фреймворком. Для оценочного теста использовались следующие версии инструментов и фреймворков: Spring Boot 2.2.4 (Java 1.8), Go Micro 1.18.0, (Go 1.13), Molecular 0.13.0 (Node.js 13.1.4), Lagom 1.6.0 (Scala 2.12.8), NATS 2.1.2. Чтобы обеспечить согласованность входных данных по тестам, мы построили Симулятор трафика (Traffic Simulator) для симуляции транспортных средств. Этот компонент основан на Simulation of Urban MObility (SUMO) [4] и предоставляет симуляцию трафика в европейском городе, используя данные из OpenStreetMap. Из Панели управления симуляция может быть настроена по количеству симулируемых транспортных средств и частоте обновления. Результаты, представленные в этой статье, получены из симуляций с 10 транспортными средствами, и они обновляют свое местоположение каждые 5 секунд.

Машина, на которой проводились тесты, имеет процессор Intel Core i5 и 16 ГБ ОЗУ. Все микросервисы контейнеризованы с использованием Docker и развернуты с использованием Docker Compose, так как это популярный выбор для достижения платформенно-независимой стратегии развертывания [25]. Мы рассматривали задержку и потребление ресурсов как ключевые критерии для измерения производительности разных фреймворков. Другой метрикой ресурсов является объем приложения, заданный размером образов Docker.

Выбранный пример использования представляет некоторые типичные типы микросервисов, которые должны быть приняты во внимание при оценке приложения. Сопоставитель карт (Map Matcher) изображает сервис, который потребляет внешний API, Сопоставитель загрязнения (Pollution Matcher) постоянно обменивается данными с внешней базой данных, в то время как Калькулятор платы (Toll Calculator) выполняет все вычисления внутренне.

6.2 Медленный старт реализаций на основе JVM

Мы заметили длинные задержки в первых сообщениях, обработанных в реализациях Spring Boot и Lagom, по сравнению с последующими запросами, как проиллюстрировано на Рис. 2.

Причина такого странного поведения, которое не найдено в других реализациях, лежит в фазе прогрева Java Virtual Machine (JVM) [16]. В этом тесте, чтобы уменьшить эффекты фазы прогрева, мы оцениваем производительность фреймворка только после пяти итераций сообщений, т.е. пропуская первые 50 сообщений.

Рисунок 2: Длинная задержка для первых сообщений в Lagom.

Рисунок 2: Длинная задержка для первых сообщений в Lagom.

6.3 Сквозная производительность задержки

Рис. 3 суммирует сквозную задержку каждого фреймворка. Все четыре реализации показывают схожее поведение в отношении задержки,

хотя и в разной степени. Есть еще некоторые заметные паттерны, общие для всех реализаций. Например, самым медленным микросервисом всегда является Сопоставитель загрязнения (Pollution Matcher), который должен обращаться к базе данных PostGIS, он составляет от 73.27% в Lagom до 90.59% от общего времени в реализации Go Micro. В противоположность этому, Калькулятор платы (Toll Calculator) имеет минимальный вклад в общее сквозное время, поскольку он может выполнять все процессы внутренне. Из результатов ясно, что доступ к базе данных очень медленный по сравнению с другими задачами, связанными с вводом-выводом. Это иллюстрирует трудности в управлении состоянием сервиса, в котором они должны быть экстернализированы в базу данных, чтобы создать полностью без状态的ные сервисы. Во многих дизайнах микросервисы вынуждены следовать принципу 12-факторного приложения, т.е. быть без状态ными, но вообще либо очень трудно, либо не оптимизировано строить приложения исключительно из без状态ных микросервисов.

Накладные расходы на коммуникацию более рассеяны для Lagom и Spring, в то время как Go Micro и Molecular имеют более последовательную задержку. Даже с более медленной коммуникацией, Lagom в общем performs лучше, чем Go Micro.

Рисунок 3: Сравнение производительности задержки.

Рисунок 3: Сравнение производительности задержки.

6.4 Потребление ресурсов

6.4.1 Размер образов Docker

Мы оценили размер образов Docker, произведенных каждым фреймворком, так как меньшие образы могут быть развернуты и созданы быстро, приводя к более быстрым циклам обновления [14]. В этой установке мы использовали образы на основе Alpine: Spring использует openjdk-8-jre-alpine, Lagom использует openjdk-8-jre-alpine, Molecular использует mhart/alpine-node:10, и Go Micro использует базовый образ golang как образ сборки и scratch как контейнер развертывания.

Результаты суммированы на Рис. 4. Поскольку приложения Go могут быть собраны как бинарные файлы, они могут использовать scratch - минимальный пустой образ Docker. Поэтому сервисы, разработанные на этом языке, очень компактны по сравнению с другими, например, Сопоставитель загрязнения, написанный на Go Micro, на 78% меньше реализации с Lagom (33.6 МБ против 156 МБ). Molecular также имеет способность создавать меньшие докеризированные сервисы по сравнению с Lagom или Spring Boot, так как эти два фреймворка требуют JVM для запуска исходного кода.

Рисунок 4: Сравнение размеров образов Docker.

Рисунок 4: Сравнение размеров образов Docker.

6.4.2 Использование CPU и памяти

Как видно на Рис. 5, Lagom и Spring дают гораздо более высокое потребление ресурсов, чем два других фреймворка. Интересно, что в то время как Lagom имеет более высокое использование CPU на сервисе Map Matcher, чем Spring, и ниже, чем для Pollution Matcher, в случае использования памяти результаты обратные. Смотря снова на Рис. 3, задержка для Map Matcher самая низкая с Spring, но этот фреймворк также показывает самую высокую задержку в Pollution Matcher. Lagom получает немного более низкую общую сквозную задержку, чем Go Micro, но с гораздо более высоким потреблением ресурсов, поэтому важно смотреть на оба аспекта при решении о фреймворке.

Более низкое потребление CPU и памяти и маленький размер образов сервисов Go Micro делают его самым эффективным фреймворком в использовании ресурсов из четырех.

Рисунок 5: Потребление CPU и памяти микросервисов, реализованных
          разными фреймворками.

Рисунок 5: Потребление CPU и памяти микросервисов, реализованных разными фреймворками.

7. ОБСУЖДЕНИЕ

Три из четырех фреймворков, изученных в этой работе (Lagom, Molecular и Go Micro), поощряют разработчиков структурировать протокол связи перед разработкой фактических микросервисов. В противоположность этому, Spring Boot не заставляет разработчиков следовать определенному стилю кода для определения API приложения. Одна из возможных причин - то, что Spring Boot - это фреймворк общего назначения, не разработанный специально для микросервисов. Этот факт подчеркивает важность шаблона коммуникации в распределенных системах в целом и в микросервисах в частности.

В теории, разделение сервисов описывается как одна из самых важных особенностей микросервисов. Однако в реальности есть несколько вызовов для реализации полной независимости между микросервисами. Например, общие библиотеки между микросервисами улучшают производительность разработчиков, но также создают зависимости. В нашей реализации JSON выбран как формат сообщений, обмениваемых между сервисами, потому что он не создает специфических требований для микросервисов в сериализации/десериализации. Если вместо этого используется Protocol Buffer, это заставляет каждый микросервис использовать ProtoBuf. Однако, учитывая, что реализации ProtoBuf доступны для многих языков программирования, разработчики все еще имеют много опций для разработки своих сервисов. В другом крайнем случае, использование некоторых платформенно-специфических протоколов, таких как Spring HTTP Invoker, заставляет и сервер, и клиент быть написанными на языке JVM.

Для облачно-нативной архитектуры, такой как микросервисы, совместимость становится более значимой, чем когда-либо. Принятие микросервисного фреймворка, использующего стандарты или популярные инструменты, может быть гораздо более выгодным для организации в долгосрочной перспективе. В этом отношении, как один из самых популярных программных фреймворков, Spring Boot/Spring Cloud предоставляет разработчикам четкое преимущество для построения микросервисов, так как этот фреймворк имеет обширный уровень поддержки и интеграции, доступной. И Go Micro, и Molecular предоставляют менее опинионизированный подход к построению микросервисов. Lagom сильно полагается на платформу Lightbend и Akka, так что это может потребовать дополнительных усилий для развертывания на других платформах.

Разработка микросервисов в частности, или облачно-нативных приложений в общем, полагается на много разных уровней абстракции, которые могут значительно ухудшить производительность. Архитекторы программного обеспечения и разработчики также должны держать это в уме при выборе технологического стека для приложения. Например, наши результаты показывают, что Molecular может достичь хорошей сквозной производительности задержки, но при развертывании с использованием Docker, Go Micro может производить гораздо меньшие образы, что может быть выгодно на ограниченных ресурсах. Аналогично, языки на основе JVM могут привести к большим образам Docker и более высокому потреблению ресурсов. Вместе с проблемой прогрева JVM, это может быть не лучшим выбором для чувствительных к задержке приложений.

8. ЗАКЛЮЧЕНИЕ

В этой работе мы представили оценку фреймворков микросервисов через разработку примера приложения, которое включает как внутреннюю, так и внешнюю коммуникацию, запрос данных из внешней базы данных и использует Docker для развертывания. Мы определили три основные категории сравнения: Для функциональных возможностей мы исследовали три категории, которые являются зрелостью, поддержкой разработки и встроенными функциями; для шаблонов проектирования мы категоризировали их в шесть групп, как представлено в Таблице 2; для производительности мы полагались на два основных критерия, которые являются сквозной производительностью задержки и потреблением ресурсов. Критерии, упомянутые в нашей оценке, могут быть расширены для использования как фреймворк сравнения для выбора стека разработки для приложения на основе микросервисов.

Из результатов, представленных в этой работе, ясно, что нет универсального решения при выборе фреймворка микросервисов. Это сильно зависит от специфических функциональных и нефункциональных требований приложения. Все фреймворки, упомянутые в этой статье, так же как и большинство других доступных опций, могут предоставить абстракцию и шаблонный код, чтобы помочь разработчикам иметь дело со сложностями, обычно найденными в распределенных системах, таких как микросервисы. Как показано в разделе оценки, совместимость - один из самых важных критериев для максимизации гибкости в выборе инструментов. Например, тот факт, что Lagom разработан, чтобы сильно полагаться на Akka и платформу Lightbend, или Molecular использует пользовательское соглашение об именовании для очередей сообщений, может вызвать проблемы интеграции с другими микросервисами. Относительно шаблонов проектирования, все фреймворки следуют асинхронной, событийно-ориентированной архитектуре с поддержкой других возможностей, таких как распределенная трассировка или отказоустойчивость. Когда дело доходит до сравнения производительности, наши результаты показывают, как использование языков на основе JVM может привести к более тяжелым образам Docker и более высокому потреблению ресурсов.

Дизайн нашего теста, однако, все еще ограничен, чтобы предоставить всестороннее сравнение между выбранными фреймворками. Хотя мы старались изо всех сил иметь похожую реализацию в разных фреймворках/языках, все еще есть некоторые специфические функции, которые не могут быть легко переведены в другие реализации. Кроме того, взаимодействие между микросервисами нашего дизайна - только простая цепочка, которая не может передать более сложные схемы взаимодействия.

9. БУДУЩАЯ РАБОТА

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

10. БЛАГОДАРНОСТИ

Эта работа получила финансирование от Федерального министерства экономики и энергетики (BMWi), Германия, по гранту № 01MA17008, проект Industrial Communication for Factories (IC4F).

ЛИТЕРАТУРА

  1. Carlos M Aderaldo, Nabor C Mendonca, Claus Pahl, and Pooyan Jamshidi. 2017. Benchmark requirements for microservices architecture research. In 2017 IEEE/ACM 1st International Workshop on Establishing the Community-Wide Infrastructure for Architecture-Based Software Engineering (ECASE). IEEE, 8-13.
  2. Marcelo Amaral, Jorda Polo, David Carrera, Iqbal Mohomed, Merve Unuvar, and Malgorzata Steinder. 2015. Performance evaluation of microservices architectures using containers. In 2015 IEEE 14th International Symposium on Network Computing and Applications. IEEE, 27-34.
  3. Kapil Bakshi. 2017. Microservices-based software architecture and approaches. In 2017 IEEE Aerospace Conference. IEEE, 1-8.
  4. Michael Behrisch, Laura Bieker, Jakob Erdmann, and Daniel Krajzewicz. 2011. SUMO-simulation of urban mobility: an overview. In Proceedings of SIMUL 2011, The Third International Conference on Advances in System Simulation. ThinkMind.
  5. Hai Dinh-Tuan, Felix Beierle, and Sandro Rodriguez Garzon. 2019. MAIA: A Microservices-based Architecture for Industrial Data Analytics. In 2019 IEEE International Conference on Industrial Cyber Physical Systems (ICPS). IEEE, 23-30.
  6. Mikhail G Dozmorov. 2018. GitHub statistics as a measure of the impact of opensource bioinformatics software. Frontiers in bioengineering and biotechnology 6 (2018), 198.
  7. Mohamed Fayad and Douglas C Schmidt. 1997. Object-oriented application frameworks. Commun. ACM 40, 10 (1997), 32-38.
  8. Mohamed E Fayad, David S Hamu, and Davide Brugali. 2000. Enterprise frameworks characteristics, criteria, and challenges. Commun. ACM 43, 10 (2000), 39-46.
  9. Martin Garriga. 2017. Towards a taxonomy of microservices architectures. In International Conference on Software Engineering and Formal Methods. Springer, 203-218.
  10. Sandro Rodriguez Garzon and Axel Kupper. 2019. Pay-per-Pollution: Towards an Air Pollution-aware Toll System for Smart Cities. In 2019 IEEE International Conference on Smart Internet of Things (SmartIoT). IEEE, 361-366.
  11. Stephan Huber and Christoph Rust. 2016. Calculate travel time and distance with OpenStreetMap data using the Open Source Routing Machine (OSRM). The Stata Journal 16, 2 (2016), 416-423.
  12. Ralph E Johnson. 1997. Components, frameworks, patterns. In Proceedings of the 1997 symposium on Software reusability. 10-17.
  13. Ralph E Johnson and Brian Foote. 1988. Designing reusable classes. Journal of object-oriented programming 1, 2 (1988), 22-35.
  14. Jaewook Kim, Tae Joon Jun, Daeyoun Kang, Dohyeun Kim, and Daeyoung Kim. 2018. GPU Enabled Serverless Computing Framework. In 2018 26th Euromicro International Conference on Parallel, Distributed and Network-based Processing (PDP). IEEE, 533-540.
  15. James Lewis and Martin Fowler. 2014. Microservices. MartinFowler.com (2014).
  16. David Lion, Adrian Chiu, Hailong Sun, Xin Zhuang, Nikola Greevski, and Ding Yuan. 2016. Don't get caught in the cold, warm-up your {JVM}: Understand and eliminate {JVM} warm-up overhead in data-parallel systems. In 12th {USENIX} Symposium on Operating Systems Design and Implementation ({OSDI} 16). 383-400.
  17. Michael Mattsson. 1999. Effort distribution in a six year industrial application framework project. In Proceedings IEEE International Conference on Software Maintenance-1999 (ICSM'99).'Software Maintenance for Business Change' (Cat. No. 99CB36360). IEEE, 326-333.
  18. Nora McDonald and Sean Goggins. 2013. Performance and participation in open source software on github. In CHI'13 Extended Abstracts on Human Factors in Computing Systems. 139-144.
  19. Maurizio Morisio, Daniele Romano, and Ioannis Stamelos. 2002. Quality, productivity, and learning in framework-based development: an exploratory case study. IEEE Transactions on Software Engineering 28, 9 (2002), 876-888.
  20. World Health Organization. 2018. Ambient (outdoor) air pollution. https://www.who.int/en/news-room/fact-sheets/detail/ambient-(outdoor)-air-quality-and-health
  21. Claus Pahl and Pooyan Jamshidi. 2016. Microservices: A Systematic Mapping Study. In CLOSER (1). 137-146.
  22. Daniel Richter, Marcus Konrad, Katharina Utecht, and Andreas Polze. 2017. Highly-available applications on unreliable infrastructure: Microservice architectures in practice. In 2017 IEEE International Conference on Software Quality, Reliability and Security Companion (QRS-C). IEEE, 130-137.
  23. Savitha Srinivasan. 1999. Design patterns in object-oriented frameworks. Computer 32, 2 (1999), 24-32.
  24. I Akshitha Sriraman and Thomas F Wenisch. 2018. \(\mu\) suite: a benchmark suite for microservices. In 2018 IEEE International Symposium on Workload Characterization (IISWC). IEEE, 1-12.
  25. Takanori Ueda, Takuya Nakaike, and Moriyoshi Ohara. 2016. Workload characterization for microservices. In 2016 IEEE international symposium on workload characterization (IISWC). IEEE, 1-10.
  26. Ying Wang, Su Song, SHIYONG QIU, Lu Lu, Yilin Ma, Xiaoyi Li, and Ying Hu. 2017. Study on international practices for low emission zone and congestion charging. Beijing, World Research Institute (2017).