Сервисно-ориентированная архитектура
RichApp
Опубликована 13 мая 2020 в 13:39:24Обновлена 13 мая 2020 в 13:40:04

Сервисно-ориентированная архитектура

soazeromqpython3
Сервисно-ориентированная архитектура, RichApp

В сервисно-ориентированной архитектуре (далее SOA - service-oriented architecture) используется модульный подход. Каждый сервис независим и легко заменяем. Сервисы могут быть распределёнными.

Для взаимодействия сервисов используется платформо-независимый протокол. Т.е. сервис может быть реализован на любом языке программирования и работать на любой ОС.

В статье рассматривается взаимодействие SOA сервисов с помощью ZeroMQ (библиотека для реализации обмена сообщениями).

Коммуникации с помощью ZeroMQ

ZeroMQ скрывает логику по настройке и работе транспортного уровня. Всю низкоуровневую работу библиотека берёт на себя. Пользователь работает с библиотечным объектом Socket.

При инициализации сокета используется два параметра. Первый - точка подключения (далее endpoint). В endpoint задаётся транспортный уровень. Второй - это тип подключения сокета. Тип подключения задаёт способ коммуникации между клиентом и сервером. Затем сокет создается в качестве сервера на указанном endpoint или подключается как клиент на указанный endpoint.

Например мы хотим использовать TCP endpoint. Тогда для сервера указывается ip интерфейса и порт на котором ожидать подключения: "tcp://127.0.0.1:8000". Чтобы сервер ожидал подключения по всем интерфейсам используется endpoint: "tcp://*:8000". Если севрер поднимается на всех интерфейсах, то клиенту вместо * надо указать конкретный ip адрес для подключения.

Если сервисы работают на одном сервере, то можно использовать в качестве транспорта ipc (Inter-Process Communitaction). Для этого в качестве endpoint указывается путь к файлу: "ipc:///tmp/queue.socket".

В статье будут рассмотрены следующие типы подключений:

  • Push-Pull — push сокет (сервер) отправляет сообщения, а pull сокеты (клиенты) забирают или push сокеты (клиенты) отправляют на pull сокет (сервер).
  • Request-Reply — req сокеты (клиенты) отправляют сообщения на rep сокет (сервер) и в ответ на каждое сообщение получают сообщение от rep сокета.
  • Publish-Subscribe — pub сокет (сервер) отправляет сообщения на все sub сокеты (клиенты) или pub сокеты (клиенты) отправляют сообщения на sub сокет (сервер).

Более подробную информацию про выбор транспорта и типа подключения ищите на сайте ZeroMQ.

Потоковая обработка данных

Данные идут последовательно слева на право в сервис Коллектор. Коллектор ожидает на вход json в заданном формате. В этом формате Источник №1 и Источник №2 отправляют данные на Коллектор.

Источник №3 и Источник №4 отдают данные в виде строки. Для преобразования строки в json используется сервис Адаптер. Адаптер переводит строки в json формат Коллектора и передает данные на Коллектор.

Для приёма json Коллектор создаёт сервер с Pull сокетом. Источник №1, 2 и Адаптер отправляют на сервер Коллектора с помощью Push сокета.

Адаптер создаёт сервер с Pull сокетом для обработки строк. Источник №3, 4 отправляют строки на сервер Адаптера с помощью Push сокетов.

Источник №1 и Источник №2 отправляют данные в формате json напрямую в сервис Коллектор. Источник №3 и Источник №4 отправляют строки в сервис Adapter, которые отправляет json в Коллектор
Потоковая обработка данных

Например, сервис Адаптер не справляется с нагрузкой и его надо распределить на несколько машин. Это можно сделать не меняя архитектуры в Источнике №3,4 и Коллекторе.

Добавим прокси сервис в который перенесём Pull сервер для приёма строк. Добавляем на прокси сервер Push сервер в который передаём строки, полученные из Pull сервера. Адаптер №1, 2 Забирают строки с помощью Pull сокетов с Push сервера Прокси.

Масштабирование сервиса Адаптер
Масштабирование сервиса Адаптер

API сервис

Сервис API (Application Programming Interface) реализует удаленный вызов процедуры по протоколу json-rpc2. Он ожидает на вход json. Из полученного json-а сервис получает имя метода и параметры. Затем сервис вызывает метод с параметрами и возвращает результат в виде json-а.

Сервис API создает Reply сокет. Клиенты к нему подключаются с помощью Request сокетов. На картинке ниже представлен принцип работы сервиса API. Сервис обрабатывает клиентов последовательно.

Сервис API обрабатывает запросы от клиентов последовательно
Сервис API

Рассмотрим картинку "Сервис API". Белые прямоугольники под Клиент #1, API , Клиент #2 — время. Стрелочки от Клиентов к API это json-rpc2 вызов хранимой процедуры. Стрелочки от API к Клиентам это результат запроса.

Как мы видим на картинке второй запрос от Клиента #1 выполняется во время обработки запроса от Клиента #2. Он встал в очередь и выполнился после запроса от Клиента #2. Время выполнения увеличилось почти в 2 раза — зависит от момента времени в который пришёл запрос.

С увеличением клиентов эта очередь будет расти. К примеру одновременный запрос от 10 клиентов увеличит время выполнение 10-ого запроса в 10 раз. Допустим время выполнения одного запроса 20 миллисекунд. Тогда мы получаем задержку в 200 миллисекунд.

Для уменьшения задержки надо воспользоваться паттерном Request-Reply Broker. Добавляется промежуточный сервис Broker который распределяет запросы на несколько Reply серверов. Например мы сделаем 10 Reply серверов. Тогда 10 одновременных запросов от клиентов будут выполнены без задержек.

Система уведомлений

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

Система уведомлений
Система уведомлений

В данном примере у нас один Publish сервис API и несколько сервисов Subscriber - Клиент #1 и Клиент #2. Чтобы сделать несколько сервисов Publishers и Subscribers надо добавить промежуточный сервис. В нём будут созданы Pub сокет и Sub сокет. Он будет получать сообщения от Publish клиентов и раскидывать их по Subscribe клиентам.

Pub-Sub многие ко многим
Pub-Sub многие ко многим

На рисунке выше сервис Dealer принимает по одному сообщению от сервисов Publisher #1-3. Затем он каждому Subscriber #1-3 отправляет три полученных сообщения notify #1-3.

Итог

Сервисно-ориентированный подход легко реализуется с помощью библиотеки ZeroMQ. Библиотека предоставляет большие возможностей по реализации взаимодейстия сервисов. В статье мы рассмотрели некоторые из них.