CQRS + Event Sourcing: (верно ли это) Команды обычно передаются точка-точка, в то время как события домена передаются через pub / sub?


12

Я в основном пытаюсь обернуть голову вокруг концепции CQRS и связанных понятий.

Хотя CQRS не обязательно включает в себя Messaging и Event Sourcing, кажется, что это хорошая комбинация (как видно из множества примеров / блогов, объединяющих эти концепции)

Учитывая вариант использования для изменения состояния чего-либо (скажем, для обновления Вопроса о SO), считаете ли вы следующий поток правильным (как в передовой практике)?

Система выдает агрегатный UpdateQuestionCommand, который можно разделить на несколько более мелких команд: UpdateQuestion, который предназначен для корня совокупного вопроса, и UpdateUserAction (для подсчета точек и т. Д.), Ориентированного на корень совокупного пользователя. Они отправляются асинхронно с использованием обмена сообщениями точка-точка.

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

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

Общий вопрос: действительно ли лучше всего, чтобы команды передавались точка-точка (то есть: получатель известен), тогда как события передаются (т. Е. Получатель (получатели) неизвестны)?

Исходя из вышесказанного, каково было бы преимущество / недостаток, позволяющий транслировать Команды через pub / sub вместо двухточечной?

Например: при трансляции команд во время использования Saga могут возникнуть проблемы, поскольку Saga должна играть посредническую роль в случае сбоя одного из агрегатных корней, поскольку сага не знает, какие агрегатные корни участвуют с самого начала. ,

С другой стороны, я вижу преимущества (гибкость), когда команды вещания будут разрешены.


Хорошо написанный вопрос между прочим.
Дав

Ответы:


19

Отказ от ответственности: я делаю только свои первые шаги в мире CQRS, но я могу предложить свое текущее понимание вопроса, и мы посмотрим, подтвердят ли другие. Все, что я пишу ниже, имеет основную тему «как я вижу» и не является авторитетным.

Случай 80%

Чтобы ответить на ваш вопрос, команды действительно являются делом «точка-точка». Когда команда входит в контроллер (веб-приложение MVC), этот контроллер затем просит диспетчера команд найти один и только один соответствующий обработчик команд и передает работу этому обработчику.

Почему бы не опубликовать?

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

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

пример

Это можно сравнить с реальной жизнью. Если у вас трое детей, зайдите в комнату и просто закричите «Очистите ванную», у вас нет гарантии, что кто-то это сделает, и выскочит, если это не будет сделано дважды (если у вас есть послушные дети ;-) лучше, если вы назначите конкретного ребенка делать то, что вы хотите сделать.

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


имеет много смысла. Отличная аналогия :)
Герт-Янв

Вы потеряли меня в .. When a command enters a controller (MVC webapp)-? Вы используете RESTful? или какие-то гибридные конечные точки API? Не могли бы вы добавить пример
Петр Кула

@ppumkin мы использовали конечную точку WebAPI, которая будет вызываться нашим веб-приложением каждый раз, когда ему необходимо выполнить команду. Например. если пользователь хочет добавить комментарий, веб-приложение отправляет запрос POST example.com/api/Post/AddPostComment.
Дав

1

Я согласен, что инициирующая система, как правило, никогда не ожидает, что команда будет обработана несколькими целевыми системами:

  • Команды обычно никогда не посылают и молятся - инициирующая система команды обычно хочет асинхронную обратную связь, поскольку ход и результат команды имеют место (например, события состояния, такие как acknowledgementуспешные completionили failureмогут быть опубликованы целевой системой для информирования инициирующей команды). система).
  • Если было задействовано несколько целевых систем, инициирующая система получит несколько (возможно, противоречивых) результатов для команды (например, цель 1 успешно выполнена, но цель 2 не выполнена). Это потребовало бы дополнительной сложности при определении фактического состояния исходной команды (например, будет ли командная транзакция считаться успешной, только если все цели выполнены успешно? Нужно ли откатить команду или выполнить компенсацию в успешных целях, если одна из целей потерпела неудачу? и т.д.). Это привело бы к нежелательной связи и сложности между исходной и целевой системами.

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

  • Аудиторские цели
  • Инструментарий и эксплуатационные показатели (например, нагрузка, бизнес-аналитика и т. Д.)
  • Сложная обработка событий или потоковая обработка событий «подслушивающие устройства» - эти системы могут обнаруживать ошибки или нарушения в командах (например, частота команд или корреляция между различными комбинациями команд и событий) и могут вызывать оповещения или корректирующие действия (часто в форма далее, разные типы команд).
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.