CQRS 是 saga/process manager 同步执行一组相关命令的最佳方法吗?

Ben*_*son 4 masstransit cqrs saga .net-core

我有一个 CQRS .NET Core 服务,目前每个命令都有一个端点。有时,一组命令构成系统中的单个操作(例如创建评估),一旦前一个命令将数据提交到数据库,就必须同步执行 3 个左右的命令(这是因为旧数据库设计)。

目前,这是由客户端处理的,其中每个命令在它之前的依赖命令完成后触发(使用承诺)。

值得注意的是,这些命令有时也会单独执行,如果将它们组合成一个命令,最终会变得庞大且难以测试。

我想要做的是创建一个单一的端点来管理像我们的创建评估一样的操作,它必须一个接一个地执行以下命令:

  1. 用户创建
  2. 评估已创建
  3. 评估注册到客户

我一直在走使用 MassTransit 传奇/状态机/流程管理器的路线,但我对它的工作越多(并且我的理解提高得越多),我就越认为这似乎是矫枉过正而不是正确的方法(如这些是命令而不是事件,并且都在单个有界上下文中)。

流程管理器看起来合适吗?如果合适,MassTransit 状态机实现是要走的路还是我应该查看其他来源?或者我应该只是简单地创建一个端点,一次触发一个命令(即在 ASP 控制器中有这个同步代码)?

Ale*_*rev 8

澄清UserCreated一下,这不是命令,而是事件。

您在这里有三个选择:

  • 而是建立一个反应式系统。因此,在CreateUser(顺便说一句,这里不是一种很好的语言,因为您从未创建用户,他们在您的系统中注册)您发出后UserCreated,这会导致发送命令CreateAssessment等的反应。
  • 使用 MT saga 作为流程管理器。如果您需要确保有些复杂的工作流以您期望的方式完成(或失败),状态机非常适合。
  • 使用 MT courier 特性实现分布式事务。您将有一系列活动、行动和补偿行动(逆转)。

我会亲自分析我的问题,以找出在我返回用户并说“没关系”之前我需要做的最低限度的事情。其余的可以在幕后异步完成。与其说是技术,不如说是领域分析。

2019 年 4 月 12 日更新,回答以下评论之一:

同样,当前应用的术语存在问题。许多消息传递库,如 MassTransit、Rebus 或 NServiceBus,使用saga一词来表示流程管理器。

使用原始术语,流程经理处理可能存在偏差和并行化的整个流程。另一方面,Sagas 实现了单流程流程。当传奇中的任何一步失败时,之前发生的一切都会使用补偿动作恢复。传奇没有编排,因为每一步都是独立的,当一个步骤完成时,下一步就会被执行。Sagas 始终是无状态的,如果需要为下一步包含一些附加信息,则 saga 活动需要将其放入有效负载中。

根据定义,流程管理器是协调器。它从不自己完成工作,而是指示其他组件完成工作。然后,通过监听事件,流程管理器决定流程应该如何流动。流程管理器可以启动补偿操作,但它本身并不执行该操作,而是指示另一个组件执行该工作。为了保持流程的当前状态,流程管理器是有状态的。

  • 命令与事件之间的区别非常清楚。命令表达了做某事的意图,事件传达了某事已经发生的事实。命令式的命令意味着发送者告诉接收者做某事。但它还没有完成。命令处理可能会失败,并且在这种情况下不会产生任何事件。这种区别很重要。 (2认同)