Микросервисы и мониторинг данных

Задача: регистрировать некие объекты и с определенной периодичностью запрашивать от них информацию для последующего вывода пользователю по запросу.

Первоначальная задумка заключалась в разделении предметной области на 2 контекста:

  1. Контекст текущей информации об объектах;
  2. Контекст опроса

Микросервис опросов запрашивал бы данные и публиковал события с результатами опроса. В свою очередь микросервис текущей информации об объектах подхватывал события и обновлял бы свою локальную базу.

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

Просмотрел раздел замечательной книги на msdn, где микросервис рассматривается как логическая структура, которая иногда может состоять из нескольких сервисов (физической реализации) с общим доступом к базе данных: https://docs.microsoft.com/ru-ru/dotnet/architecture/microservices/architect-microservice-container-applications/logical-versus-physical-architecture

Исходя из этой статьи напрашивается второй подход:

Объединить контексты в единый микросервис, состоящий из:

  1. Сервиса для вывода информации об объектах
  2. Сервиса опросов - для обновления информации об объектах

Вопрос: исходя из описанного, какой подход предпочтительнее с точки зрения микросервисной архитектуры?

UPD В перспективе нужно будет выводить статистическую информацию (Сервис статистики), накопленную от запрашиваемых объектов за определенное время. Но такие обширные данные совершенно не нужны для сервиса текущей информации.


Ответы (1 шт):

Автор решения: Алексей Якубин

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

Архитектура состоит из следующих компонентов:

  • Сервис-источник информации
  • Брокер (шина данных)
  • Сервис статистической информации (агрегированные данные, данные за прошлые периоды и т.п.)

Процесс обмена информацией выстраивается следующим образом:

  1. Сервис-источник информации публикует в шину событие вроде DataXyzReceived, содержащее свои сырые данные.
  2. Сервис-потребитель получает событие, делает необходимые преобразования с данными и складывает в свою базу в готовом для запроса пользователем виде.

Таким образом вы получите следующие преимущества:

  1. Отсутствие промежуточного "сервиса-перекладывальщика" данных, данные публикуют непосредственно их источники. Нет лишнего сервиса.
  2. Сервисы-источники публикуют непосредственно те данные, с которыми работают - мы не вносим в них не относящегося к их задачам дополнительного контекста (моделей). Сервис-публикатор ничего не знает о существовании сервиса-потребителя и наоборот. Слабая связность.
  3. Версионирование осуществляется через версии контракта данных в публикующихся событиях - мы можем сначала обновить сервис потребитель (который сможет принимать события уже двух версий), а потом раскатывать вторую версию на сервис-источник. Независимое развёртывание.
  4. Отсутствие состояния, поэтому экземпляров сервиса-источника и сервиса-потребителя может быть (в теории) сколько угодно. Горизонтальная масштабируемость.
  5. Сырые данные хранятся в базе основного микросервиса, а статистические в базе другого. Минимизация дублирования данных.

Получаем и некоторые недостатки:

  1. Необходим надёжный и масштабируемый брокер сообщений, сегодня популярны RabbitMQ и Kafka.
  2. Объём данных таки возрастает за счёт хранения агрегированного представления, но это компенсируется улучшенным временем отклика от подсистемы хранения (выдавать готовые данные проще, чем калькулировать агрегации на лету).
→ Ссылка