EDA - event-driven architecture

Концепция

То, что произошло в прошлом, не может измениться (и не должно), это означает, что и если событие породило неудовлетворительные действия (например изменения с ошибкой), то исправить ситуацию можно только новым событием, которое сделает ситуацию удовлетворительной (исправит ситуацию).

Плюсы

  • потребитель реагируют на события по мере их поступления (используя модель подписки и параллельной обработки)
  • ускоряется запрос-ответ (ведь уменьшается физическая и временную связь между клиентами и сервисами)
  • данные событий могут быть обогащены (посредством потребителя-обогатителя)
  • события не требуют ответа и по своей сути асинхронны
  • потребитель может работать в режиме брокера (принимать сообщения, но обрабатывать их асинхронно)
  • заставляет участников общения, отказаться от распределенных транзакций (обеспечивает лучшую поддержку согласованности между взаимодействием процессов и постоянными переходами между внутренними состояниями)
  • состояние системы может быть построено или восстановлено из журнала событий (правда восстановление является очень нетривиальной задачей + нарушает концепцию EDA)
  • отвечает на вопросы: что первично, где меняется, куда переносится
  • упрощает MDM (англ. master data management - управление основными данными) в информационных системах организаций (как правило — в условиях нескольких информационных систем)
  • наводит порядок в процессе миграции данных (где данные появляются, где редактируются, сегментирование и приоритеты)
  • помогает менять окружение (замена производителя событий или потребителей событий)
  • упрощает подключение нового потребителя / замены старого
  • создает единообразное объединение подсистем на различных платформах (легкая замена подсистем)

Минусы

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

Брокер между участниками

Плюсы

  • потребитель не обязан быть доступен в то время, когда производитель делает запрос (таким образом, мы достигаем более высокой устойчивости к сбоям сети и вычислений)
  • события сохраняются брокером, что позволяет производителям событий избегать блокировки (но блокировки на стороне потребителя не отменяются)
  • создатель события не знает получателей события (существует минимальная связь с точки зрения имен очередей и форматов событий)
  • единое место связей (если использовать брокер как единую точку связи всех приложений), таким образом создает единую точку анализа полученных/отправленных данных

Минусы

  • очередь в брокере может быть переполнена и за этим нужно следить
  • брокер сообщений это отдельное решение (которое нужно реализовать / приобрести, настроить и мониторить)

Оркестрация

Изменение данных с помощью событий (а добавление/изменение данных это событие) добавляет в архитектуру приложения еще одну модель работы с данными, называемую повествование (в простонародье - сага). 

При работе с повествованиями выбирают один из подходов работы (всего мне известно 2 вида подхода):

  1. Хореография — распределение принятия решений и упорядочения действий между участниками повествования (в основном которые общаются, обмениваясь событиями).
  2. Оркестрация — централизация координирующей логики повествования в виде оркестратора. Оркестратор отправляет участникам повествования командные сообщения с инструкциями, какие операции нужно выполнить.

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

Детали оркестрирации

Единственной задачей оркестратора является рассылка инструкций участникам. Оркестратор взаимодействует с участниками в стиле «команда/асинхронный ответ». Чтобы выполнить этап повествования, он шлет участнику командное сообщение, объясняя, какую операцию тот должен выполнить.

После выполнения операции участник возвращает оркестратору сообщение с ответом. Оркестратор обрабатывает это сообщение и решает, какой этап повествования нужно выполнить дальше.

Если участник возвращает ошибку, то оркестратор так же знает о том, кого из участников нужно об этом оповестить.

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

Моделирование оркестраторов

Конечный автомат — это хорошая модель для оркестратора повествования. Он состоит из набора состояний и переходов между ними, которые инициируются с помощью событий. У каждого перехода может быть какое-то действие, которое в контексте повествования означает вызов участника. Переходы между состояниями инициируются завершением локального перехода, выполненного участником повествования. Текущее состояние и конкретный результат локального перехода определяют последующий переход и действие, которое нужно выполнить (если таковое имеется). Конечный автомат имеет эффективные стратегии тестирования. Благодаря этому использование данной модели упрощает проектирование, реализацию и тестирование повествований.

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

Давайте посмотрим работу на примере появления события в большой системе использующей EDA.

Как видно:

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

Недостатки оркестровки

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

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

Маленький итог

При создании приложений с одной конкретной функцией Вы можете создать более модульную систему. Каждое приложение выполняет определенную бизнес-функцию и вместе, как единое целое, выполняют бизнес-процесс.

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

Data Grid vs Api Service

Есть готовые решения под названием Data Grid - это подход основанный на EDA:

  1. DG на базе Tarantool https://www.youtube.com/watch?v=OPB5zvUm6gU
  2. DG на базе Apache Ignite https://www.gridgain.com/resources/blog/getting-started-with-apache-ignite-deployment-patterns
  3. Др. более простое решение или собственный велосипед (CQRS EventSource приложение)

Однако, небольшому приложению я бы рекомендовал упрощать в угоду синхронного обмена данными между Api приложениями. А вот крупному приложению все же стоит подумать над оркестратором, иначе получится как в Netflix:

Вопросы для принятия решения:

  1. собираемся ли мы поддерживать большое кол-во протоколов на вход
  2. собираемся ли мы поддерживать большое кол-во протоколов на выход
  3. собираемся ли мы поддерживать большое кол-во контрактов на вход
  4. собираемся ли мы поддерживать большое кол-во контрактов на выход
  5. нужна ли нам гибкость с использованием знакомых технологий/языках или мы не боимся привязки к стороннему ПО и др. языкам (например Lua в Tarantool)
  6. с одной стороны готовый DG выглядит быстрее, но с другой стороны нужна экспертиза
  7. в силу последних обстоятельств, возможно Apache Ignite теперь не выглядит возможным решением, т.к. не отечественное ПО и поддержку мы возможно никак не получим

Источник: 1 - 2 - 3 - 4 - 5


14.02.2011 17:52