CQRS +事件源:(是否正确)命令通常是点对点传递的,而域事件是通过pub / sub传递的?


12

我基本上是想围绕CQRS的概念和相关概念。

尽管CQRS不一定包含消息传递和事件源,但它似乎是一个很好的组合(从结合了这些概念的许多示例/博客中可以看出)

给定一个用于某种情况的状态更改的用例(例如,更新有关SO的问题),您是否认为以下流程是正确的(如最佳实践中那样)?

系统发出一个汇总的UpdateQuestionCommand,可以将其分成几个较小的命令:以Question Aggregate Root为目标的UpdateQuestion和以User Aggregate Root为目标的UpdateUserAction(对点进行计数)。这些是使用点对点消息传递异步发送的。

聚合根起作用,如果一切顺利,则分别引发事件QuestionUpdated和UserActionUpdated,它们包含外包给事件存储的状态。要保留yadayada,只是为了完整起见,此处并不是重点。

这些事件也被放在发布/订阅队列中进行广播。任何订阅者(其中可能有一个或多个创建阅读视图的投影仪)都可以自由订阅这些事件。

一个普遍的问题:最佳实践是命令之间进行点对点通信(即:接收方已知),而广播事件(即:接收方未知)吗?

假设以上所述,允许通过pub / sub而不是点对点广播命令的优点/缺点是什么?

例如:在使用Saga广播广播Commands时可能会出现问题,因为Saga在某个聚合根之一出现故障的情况下需要扮演的调解角色受到了阻碍,因为saga不知道哪个聚合根开始参与。

另一方面,我看到允许广播命令时的优势(灵活性)。


顺理成章的问题。
Dav 2012年

Answers:


19

免责声明:我只是迈出CQRS领域的第一步,但是我可以提供我目前对这件事的理解,我们将看看其他人是否证实。我在下面编写的所有内容都有一个潜在的“如我所见”主题,并且没有权威性。

80%的情况

为了回答您的问题,命令确实是点对点的事情。当命令进入控制器(MVC webapp)时,该控制器会要求命令调度程序找到一个且只有一个适当的命令处理程序,并将工作委托给该处理程序。

为什么不发布?

这是责任问题。如果事情发送一个命令,它需要的预期,这将会实现。如果您只是发布并希望某处能够找到它并对其采取行动,则不能保证会如此。通过推断,您还不知道多个处理程序是否未决定对命令执行操作,这可能导致同一更改被应用多次。

另一方面,事件本质上是信息性的,可以合理地预期零,两个或更多组件对特定事件感兴趣。我们并不在乎进行请求的更改的范围。

这可以与现实生活相提并论。如果您有三个孩子,请走进一个房间,然后大声喊“打扫浴室”,则您无法保证有人会这样做,如果不能做到两次,则请作好准备(如果您有听话的孩子;-),您应该如果您指派一个特定的孩子去做您想做的事情,情况会更好。

但是,当那个孩子完成工作时,如果大声喊出“浴室已经打扫过”,那就很方便了,这样每个想要刷牙的人都知道自己现在可以这样做了。


很有道理。很好的类比:)
Geert-Jan

你让我迷恋When a command enters a controller (MVC webapp)--?您正在使用RESTful吗?或某些混合API端点?您能补充一个例子吗?
Piotr Kula,

@ppumkin我们使用了WebAPI端点,每次需要执行命令时,Web应用程序都会调用该端点。例如。如果用户想添加帖子评论,则网络应用将向发送一个POST请求example.com/api/Post/AddPostComment
Dav

1

我同意启动系统通常不会期望命令被多个目标系统处理:

  • 命令通常是从不“发送并祈祷”的-命令的发起系统通常希望在命令的进度和结果发生时获得异步反馈(例如acknowledgement,目标系统发出的,和成功等状态事件,completionfailure可以将其发布给目标系统以通知发起者系统)。
  • 如果涉及多个目标系统,则启动系统将收到该命令的多个(可能是矛盾的)结果(例如目标1成功,但目标2失败)。这将在确定原始命令的实际状态时需要额外的复杂性(例如,仅在所有目标都成功的情况下,命令事务才被视为成功吗?如果目标之一失败,是否需要回滚命令或补偿成功的目标?等等。)。这将在启动系统和目标系统之间引入不良耦合和复杂性。

但是,仍然可以订阅额外的(非事务性的,通常是“混杂的”)用户,这些用户“窃听”系统之间发出的命令,这仍然是一个优点。

  • 审计目的
  • 仪表和运营指标(例如负载,业务分析等)
  • 复杂事件处理或流事件处理的“窃听者”-这些系统可以检测命令中的错误或不规则性(例如,命令的频率或命令和事件的不同组合之间的相关性),并可以触发警报或纠正措施(通常是在其他不同类型的命令的形式)。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.