На текущий момент существует множество готовых фреймверков для разработки приложений с использованием микросервисной архитектуры. Как правило, фреймворки разделяются на два типа — под язык, которые могут работать с разными платформами, но разработка ведется на одном языке — пример SpringBoot, Nancy, и т.д. И второй тип — под платформу, — способны работать с разными языками программирования, но запуск кода возможно выполнить лишь на выбранной платформе — пример ServiceFabric, AWS Lambda. Но практически нет мультиязычных фреймворков способных работать на разных платформах.
Наша команда занимается разработкой enterprise систем на основе микросервисов, которые содержат компоненты написанные на разных языках и часто требуется работать на различных платформах, таким образом описанная выше проблема для нас более чем актуальна. Поскольку ничего из готовых решений отвечающих таким требованиям нам не удалось найти, мы разработали свое собственное решение — Pip.Services Toolkit. Этот инструмент позволил нам вести разработку микросервисов на многих языках программирования и особо не переживать о том, где это приложение будет запускаться — в облаке или on premise.
Целью статьи является знакомство читателя с возможностями проекта без углубления в детали реализации. Если Вам интересно узнать подробней о данном инструменте, тогда прошу под кат…
Что такое Pip.Services?
При разработке мы стремились создать довольно универсальный инструмент способный перекрыть множество задач. В процессе проектирования были определены основные принципы, которые легли в качестве фундамента продукта:
- компоненты системы должны быть мало связанными с целью их легкой доработки и добавления нового функционала
- очень длительный жизненный цикл – целью было создать такой инструмент, который бы позволил осуществлять его поддержку на разных языках максимально возможное время.
- возможность разрабатывать приложения как для микросервисной архитектуры, так и для монолитной
- разработанные приложения должны иметь возможность разворачиваться на любой платформе, будь то on premises или cloud решение, причем cloud так же не должны быть зависимы от оператора
- поддержка максимального количества языков программирования применяемых в разработке с сохранением принципов работы самого инструмента, а также совместимость сервисов написанных на разных языках между собой при коммуникациях
Pip.Services Toolkit представляет обширный набор инструментов позволяющий вести разработку микросервисных и монолитных приложений с использованием популярных языков программирования. В Pip.Services Toolkit разработаны инструменты для работы со всеми необходимыми функциями и структурами данным, потребность в которых может возникнуть у разработчика, в случае отсутствия необходимых вещей их с легкостью можно дописать самостоятельно.
Pip.Services Toolkit является истинным полиглотом, при этом соблюдаются следующие концепции:
Симметричная реализация в коде
- симметрия в подходе к именованию методов, структур, типов данных. Данный подход позволяет не тратить много времени на изучение при смене используемого языка, все концептуально идентично
Сквозная совместимость
- совместимость на уровне типов данных — это означает, что типы данных будут одинаково обрабатываться в разрабатываемой системе независимо от выбранного языка программирования для разработки
- совместимость на уровне сетевого обмена между сервисами — это обеспечивает полную совместимость в протоколах обмена между сервисами написанными на разных языках программирования
- совместимость на уровне распространения и описания ошибок — независимо от выбранного языка программирования ошибки возникшие в работе сервиса всегда будут корректно декодированы и содержать стандартный набор полей, позволяющий в точности определить проблему
Для более наглядного представления о структуре, обратимся к структурной схеме инструментария.
Как было упомянуто в начале статьи инструментарий мультиязычный. На данный момент существуют реализации на 6 языках программирования, среди них есть как популярные (Java, Node.js, Python, .Net Core), так и развивающиеся (Go, Dart) – на диаграмме это серый слой.
Как видно в основе лежит набор пакетов с кросс-языковыми примитивами и общими шаблонами предназначенных для быстрой разработки собственных компонентов – на диаграмме зеленый слой. На их базе реализована библиотека основных компонентов инструментария.
Уже на основе базовых компонентов реализуются пользовательские и системные компоненты – это второй зеленый слой.
Синий слой диаграммы представляет собой набор основных библиотек для работы в определенных направлениях – это реализация контейнеров (IoC), работа с данными, синхронный обмен (RPC) и асинхронный обмен (Messaging). Они способны работать как самостоятельные компоненты, но также они обеспечивают базовые интерфейсы и принципы для построения конкретных реализаций дополнительных компонентов для работы с конкретными технологиями. Как указано на диаграмме на вершине стека, в качестве примера, реализация контейнеров для AWS и Azure, реализация работы с данными в MongoDb, а также распределенное кэширование и блокировки в Memcached и Redis.
Микросервис на Pip.Services toolkit — взгляд изнутри
Практика разработки показывает, что среди множества различных видов дизайнов, предпочтительным является построение микросервиса из слабо-связанных компонентов. Pip.Services Toolkit не накладывает на разработчиков ограничений по структуре микросервиса.
Каждый разработчик волен выбирать свой путь. Но компонентный дизайн имеет сильную поддержку в Pip.Services Toolkit. Благодаря такому подходу решается целый ряд задач:
- Упрощается разработка и тестирование отдельных компонентов.
- Каждый компонент может быть изолирован от остального кода и его зависимости в тестах заменены на простые mocks.
- Появляется возможность перенастраивать микросервис на определенную платформу, заменять инфраструктурные сервисы, коммуникацию или базы данных просто меняя состав компонентов микросервиса в конфигурационном файле без какого-либо изменения кода.
- Облегчается поддержка и ускоряется процесс внедрения инноваций. При изменении отдельных технологий основной набор компонентов не требует модификаций. Меняются, либо добавляются только отдельные компоненты непосредственно использующие новую технологию.
- Типичная структура микросервиса, состоящего из независимых компонентов, представлена на диаграмме ниже:
- Микросервис представляет из себя контейнер содержащий в себе набор компонентов для обеспечения его функционирования. Компоненты условно можно разделить на несколько групп:
- Определение внешнего интерфейса микросервиса, коммуникационных протоколов и данных (красный цвет).
- Компоненты обеспечивающие уникальную функциональность микросервиса, реализующие хранение и обработку данных, а также интерфейс для коммуникации с клиентами (зеленый цвет).
- Дополнительные компоненты для кеширования, мониторинга, настройки, синхронизации и пр. Как правила эти компоненты добавляются из стандартного набора, предоставляющий широкий выбор для интеграции с различными инфраструктурными сервисами и платформами (серый цвет).
- Для упрощения пользования микросервисом может быть реализована клиентская библиотека. Она предоставляет удобный интерфейс для работы с микросервисом и скрывает детали низкоуровневой коммуникации (синий цвет).
Для сборки микросервиса и настройки компонентов в Pip.Services Toolkit применяется конфигурационный файл. Вот пример такой конфигурации:
config.yml
---
# Container descriptor
- descriptor: "pip-services:context-info:default:default:1.0"
name: "hello-world"
description: "HelloWorld microservice"
# Console logger
- descriptor: "pip-services:logger:console:default:1.0"
level: "trace"
# Performance counter that post values to log
- descriptor: "pip-services:counters:log:default:1.0"
# Controller
- descriptor: "hello-world:controller:default:default:1.0"
default_name: "World"
# Shared HTTP Endpoint
- descriptor: "pip-services:endpoint:http:default:1.0"
connection:
protocol: http
host: 0.0.0.0
port: 8080
# HTTP Service V1
- descriptor: "hello-world:service:http:default:1.0"
# Heartbeat service
- descriptor: "pip-services:heartbeat-service:http:default:1.0"
# Status service
- descriptor: "pip-services:status-service:http:default:1.0"
Контейнер, в который обернут микросервис, читает такую конфигурацию, на основе дескрипторов, при помощи фабрик, создает необходимые компоненты, передает им конфигурационные параметры, связывает компоненты друг с другом и производит запуск активных процессов.
Такой подход позволяет проектировать унифицированные сервисы и выполнять «тонкую» настройку под конкретную задачу при помощи переменных окружения непосредственно в исполняемой среде.
Переход от монолита к микросервисам без изменения кода
Отдельно стоит отметить возможность изменения используемой приложением архитектуры без внесения изменения в исходный код. Рассмотрим данную возможность на примере.
Предположим есть фасад, который использует клиент для работы с каким либо сервисом. Например с сервисом реализующим логику работы с bluetooth маячками (beacons). При запуске в режиме монолитного приложения в конфигурационном файле будут указаны следующие секции с дескрипторами компонентов:
# Beacons components
- descriptor: "pip-services-beacons:persistence:mongodb:default:*"
- descriptor: "pip-services-beacons:controller:default:default:*"
- descriptor: "pip-services-beacons:client:direct:default:*"
Данная конфигурация фактически создает сервис beacons как часть фасада в виде монолитного кода, а взаимодействие между ними осуществляется посредствам прямого клиента, но в рамках единого контейнера, как это видно из диаграммы ниже.
Но стоит немного изменить текст конфигурации, как сервис beacons станет уже отдельным микросервисом и фасад будет работать с ним через http клиент. Для этого в конфигурации фасада уберем секции с controller и persistence, а тип клиента изменим с direct на http:
# Beacons components
- descriptor: "pip-services-beacons:client:http:default:*"
connection:
protocol: "http"
host: "any.where.com"
port: 8086
Для корректной работы необходимо указать адрес и порт теперь уже отдельно запущенного микросервиса beacons и перезапустить фасад, чтобы он прочел новую конфигурацию.
Также необходимо запустить отдельный микросервис с beacons, для этого можно воспользоваться следующей конфигурацией:
# Http Endpoint
- descriptor: "pip-services:endpoint:http:default:*"
root_path: ""
connection:
protocol: "http"
host: "0.0.0.0"
port: 8086
# Beacons API V1
- descriptor: "pip-services-beacons:service:http:default:1.0"
# Hearbeat service
- descriptor: "pip-services:heartbeat-service:http:default:1.0"
# Status service
- descriptor: "pip-services:status-service:http:default:1.0"
С точки зрения архитектуры теперь это будет выглядеть так:
Как видите, таким образом возможно создавать приложения сначала в виде монолитов, при этом не затрачивая большое количество ресурсов на развертывание, но как только у Вас возникнет потребность в масштабировании, Вам достаточно лишь изменить конфигурацию и легко перейти к микросервисам — это одно их ключевых преимуществ Pip.Services Toolkit.
Дополнительные инструменты из проекта Pip.Services
В состав Pip.Services входит не толко Pip.Services Toolkit. В процессе нашей работы мы разработали еще ряд дополнительных инструментов для удобства разработки микросервисов:
— Библиотека готовых микросервисов — содержит каталог готовых к использованию микросервисов разделенных на шесть категорий:
- Инфраструктурные микросервисы – набор инструментов для управления инфраструктурой. В набор входят инструменты для сбора логов, метрик, событий, статистики и т.д.
- Микросервисы для управления пользователями – полный спектр инструментов для регистрации пользователей, контроля доступа, фиксации пользовательских действий, настройки коммуникационных каналов и рассылки сообщений
- Микросервисы для поддержки продуктов – обеспечение двусторонней связи с пользователями, обработка пользовательских запросов
- Микросервисы управления контентом – работа со статьями, изображениями, справками и другим мультимедийным контентом.
- Микросервисы для электронной коммерции – каталоги продуктов, отзывы покупателей, обработка кредитных карт и проведение электронных платежей
- Микросервисы для Интернета Вещей — списки устройств, отслеживание состояний, контроль перемещений и прочее;
- Бенчмарки — набор утилит для тестирования производительности разработанных приложений и микросервисов.
— Библиотека шаблонов — в состав входит несколько категорий с шаблонами, среди которых есть шаблоны для разработки микросервисов, настройки рабочего пространства, шаблоны CI/CD, а также шаблоны фасадов.
— PowerShell Selenium WebDriver — разработанный драйвер для работы с Selenium из PowerShell.
Все перечисленные инструменты доступны на сайте Pip.Services.
Заключение
В завершении статьи хочется добавить, что Pip.Services Toolkit — это набор паттернов и компонентов упрощающий разработку микросервисных систем с использованием множества языков программирования и обеспечивающий развертывание на различных локальных и облачных платформах. В набор включены паттерны, облегчающие создание гибко-настраиваемых микросервисов с использованием слабо-связанных компонентов, реализующие типовые функции в передаче и обработки данных, работе с базами данных, передачи информации используя различные синхронные и асинхронные протоколы, функции мониторинга, обработки ошибок и многое другое. При этом Pip.Services Toolkit легко расширяется и может сосуществовать с другими библиотеками и фреймворками благодаря дизайну построенному на основе композиции, а не наследования.
Общие принципы и структура, а также симметричность реализации позволяют разработчикам легко переходить от одного языка на другой в самое короткое время. А интероперабельность обеспечивает полную совместимость микросервисов написанных на разных языка прямо “из коробки”.
Все микросервисы в нашей библиотеке протестированы и используются в реальных системах. Благодаря использованию Pip.Services Library в наших проектах нам удавалось сократить до 30% времени на разработку backend.
Pip.Services активно развивается, практически каждый месяц добавляются новые или расширяются уже существующие инструменты и микросервисы.
Большая часть необходимой информации уже есть на сайте, но мы все еще активно дополняем его новыми материалами и продолжаем над ним работу.
По состоянию на ноябрь 2020 года, на основе данного инструментария было реализовано более тысячи микросервисов с высокой степенью надежности, высокой скоростью разработки и легкостью интеграции. Как следствие, руководителями компании, было принято решение о полном переводе продукта в статус Open Source для того чтобы поделиться с обществом удачными решениями в архитектуре, а также обеспечить дальнейшее развитие проекта силами большего количества опытных разработчиков.
Статья задумывалась исключительно как обзорная, без детальных примеров реализации, так что прошу сильно не пинать. В следующих публикациях попробуем разобраться как же реализовать работающий микросервис с использованием данного инструментария.
Если у Вас возникли вопросы по данному инструментарию, задавайте их в комментариях или через каналы связи указанные на нашем сайте и мы обязательно на них ответим.
Ссылки: www.pipservices.org
EinflussAgent
Хотелось бы, конечно, подробностей для лучшего понимания. Могли бы сравнить свой тулкит с Dapr, например? Чем он лучше или хуже? Или это вообще несравнимые вещи?