EventSourcing в иногда подключенных системах: что, если есть два сервера?

Я недавно ударился головой, пытаясь обойти эту проблему.

сценарий с одним сервером

У вас есть клиент, который иногда подключается к одному серверу.

Недавно я снова посмотрел видео Грега Янгса о иногда подключенных системах на skillmatter.com.

Там он утверждает, что лучший способ справиться с этим:

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

Теперь все в порядке, но у меня есть несколько более сложный сценарий - один с двумя серверами: Test и Production.

mutli server secnario

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

Вы также можете думать об этом как о сценарии git merge, где вы хотите перенести все свои изменения из разветвленного удаленного хранилища A в исходное удаленное хранилище B.

Проблема в:

  1. Как только клиент отправляет свои изменения в тестовую среду, команды исчезают - так как же он может протолкнуть любые изменения в производственную среду...
  2. Также: другой пользователь может быть использован для фактической публикации нового шаблона в Production. (Например, потому что публикация выполняется парнем, а не разработчиком)

Таким образом, я полагаю, что есть два решения этой проблемы: а) Сохраните поток команд и загрузите его также клиенту - но это будет противоречить тому факту, что в системах источников событий хранятся только события; б) иметь механизм для воссоздать команды из уже зафиксированных событий. Таким образом, клиент может просмотреть версию шаблонов в Production, чтобы увидеть, какие события там еще не были отправлены. Затем он создает команды и выполняет их.

Мои вопросы:

  1. Я думаю, что только б является жизнеспособным вариантом здесь?
  2. Не нарушает ли опция b какое-либо правило / принцип получения событий и / или cqrs?
  3. Есть ли другой и даже лучший способ сделать это?

Спасибо, ребята, за ваши мысли!



ОБНОВИТЬ

Спасибо, что поделились своими мыслями. Но, похоже, мне нужно кое-что прояснить - вещь с Test and Production.

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

Теперь рассмотрим следующее: В процессе производства вы понимаете, что есть небольшая ошибка, и вы исправляете ее немедленно. Затем вы хотите перенести эти изменения обратно в тестовую среду.

Итак, теперь вопрос: что, черт возьми, является источником истины?

Мне нравится жаловаться на это, потому что большинство разработчиков знают это. В основном я вижу, что у меня есть два варианта:

  1. мерзавец

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

  1. мерзавец слияния

Предположим, что обе системы являются "книгой рекордов". В этом случае мне нужно синхронизировать события, произошедшие в тестовой среде, и события, произошедшие в производственной среде (поэтому я получаю одно и то же определение приложения в Test and Production), поэтому события из Test не просто добавляются в eventstream. производства, но отсортированы в потоке событий производств в порядке, в котором они фактически произошли. Это как мерзавец слияния

Лично я предпочитаю опцию git merge, поскольку в обеих системах это приводит к одному и тому же порядку событий. И, конечно же, это позволило бы подключенным к разным клиентам клиентам использовать тот же подход для распределенного сотрудничества: предположим, что приложение, которое мы определили в Test и опубликовали в Production с использованием этого подхода к получению событий, затем используется несколькими подключенными время от времени клиентами для фактического сбора данных., Теперь несколько клиентов могут работать вместе в одной и той же совокупной корневой синхронизации друг с другом и сервером (как в системе peer2peer), сохраняя при этом тот же порядок потока событий.

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

Итак, мой вопрос: есть ли существенный недостаток в этом "git merge"?

1 ответ

Я думаю, что вы попали в сложившуюся ситуацию из-за вашего определения книги рекордов / правды.

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

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

Обзор того, что Udi Dahan должен сказать об услугах, может помочь прояснить ситуацию

Сервис - это технический орган для определенных бизнес-возможностей. Любая часть данных или правила должна принадлежать только одному сервису.

Я полагаю, что, исходя из того, что вы используете "тест" и "производство", производственная система не имеет полномочий изменять данные, которые отправляются на тестирование; он просто использует представление этих данных. Который возвращает вас прямо к одному серверу (на самом деле: к единой книге записей).

Другие вопросы по тегам