Разбираемся с Event Sourcing

Разбираемся с Event Sourcing

@MikeAnanev

Горячая тема этой недели в сообществе clojure-russia – паттерн проектирования Event Sourcing. Нет лучшего способа разобраться в теме, чем решить по изучаемой теме практическую задачу. Поэтому я предлагаю рассмотреть архитектуру веб-приложения по покупке товаров с применением подхода Event Sourcing. Предлагаю пойти следующим путем:

  1. Разрабатываем общую архитектуру приложения.
  2. Разбираем подробно CLJS часть на клиенте (Javascript runtime). Обсуждаем, что необходимо иметь на клиенте для организации ES (CQRS)
  3. Разбираемся с CLJ частью на сервере (JVM Runtime). Обсуждаем как мы храним и реплицируем стейт.
  4. Обсуждаем дополнительные компоненты, которые могут служить фасилитаторами ES подхода
  5. Делаем summary: когда использовать ES, когда лучше нет, общие выводы.

Сам я в теме новичёк, поэтому первая версия архитектуры скорее всего будет содержать ряд недостатков. Но, тем не менее, для затравки вот драфт:

Архитектура web-приложения на базе Event Sourcing подхода

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

Приложение в целом состоит из:

  • веб или мобильный клиент. Задача клиента отображать линейку товаров и их описание, отображать личный кабинет и настройки, организовывать возможность оформления заказов, выдавать некую статистику и аналитику как по активности клиента, так и аналитическим материалам самого магазина. Также могут всплывать некие уведомление. Клиент работает по технологии websoсket.
  • JVM frontend (серверная часть) . Задача данного модуля производить коммуникацию с клиентами, обеспечивать безопасность, выполнять диспетчеризацию запросов и ответов. При соединении клиента производится его аутентификации и авторизация устройства, после чего устанавливается защищенный WS канал. В случае браузера в начале отдается JS-приложение, которое занимается установкой WS канала.
  • Request processor (серверная часть). Задача процессора выполнять бизнес-логику по выполнению операционных действий (например покупке товаров), коммуницировать с различными бакэнд службами и веб-сервисами и отдавать результат выполнения операционных команд. Также Request processor работает с OLTP базой. Доступ к OLTP базе напрямую никому не дается и все взаимодействие с ней осуществляется через API Request Processor'а (стиль микросервисов). При каждой успешной транзакции Request Processor публикует дельту изменения OLTP-базы в Message Broker в Transit-формате в асинхронном режиме. Дельта имеет структурированный вид в виде clojure map, в которой детально приведены затронутые сущности, с использованием namespased ключей.
  • Analytic module (серверная часть). Данный модуль принимает на вход команды по выполнению аналитических запросов от пользователей и отдает отчеты. Также данный модуль может принимать запросы от других модулей организации. Аналитический модуль занимается построением отчетов на основе детального лога данных из модуля Archive Log.
  • Archive log. Задача данного модуля принимать дельты изменений OLTP источника, хранить дельты от "начала времен" и делать снэпшоты, для удобства работы Аналитического модуля (Analytic module). Также Archive Log может использоваться для резервного восстановления OLTP-базы на заданную дату. Реализация Archive log может быть произведена на Hadoop.


To be continued...