流程管理器如何跟踪聚合之间的关联
How does process manager keep track of the association between aggregates
进程管理器是否使用相关 ID 或聚合特定标识来跟踪它正在管理的 进程?
为了更清楚地举个例子,请考虑 Saga on Sagas 上的图 2:
首先,Process Manager 发送 OrderConfirmed
事件是错误的,对吧?我(作为流程管理者)不能发送事件,只能发出命令。还是我错了?
其次,流程管理器如何关联来自不同聚合的 OrderCreated、SeatsReserved、PaymentReceived 事件?它是每个聚合荣誉(并复制)的相关 ID,还是特定标识符(例如,SeatsReserved 有一个引用订单聚合的订单 ID)?
最后,如果是关联 ID,谁 创建 它们?是客户端发出命令,比如PlaceOrder(order_id, correlation_id)
?是 Aggregate 接受像 PlaceOrder(order_id)
这样的命令然后发出 OrderCreated(order_id, corr_id)
事件吗?或者,是流程经理(以某种方式)对此负责吗?或者,也许相关 ID 与此无关?
感谢您的帮助。
首先我要说我的回答基于我的知识、经验和我对如何在 PHP
上执行 CQRS 的看法
First of all, Process Manager sending a OrderConfirmed event is wrong right? I (as a process manager) cannot send events, only issue commands. Or am I wrong?
是的。这是错误的。只有 Aggregates
引发 Domain Events
并执行 Commands
。也许 Microsoft 忘记显示发送到 OrderAggregate
.
的 MarkOrderAsConfirmed command
Second, how does the process manager correlate the OrderCreated, SeatsReserved, PaymentReceived events from different aggregates? Is it correlation id that each aggregate honors (and copies over), or is it specific identifiers (e.g. SeatsReserved has an Order Id that refers to the Order Aggregate)?
我使用参与该过程的 Aggregates
的 ID。本例中的关联 ID 与 OrderAggregate
的 ID 一对一映射,具有相同的生命周期。
Finally, if it is the case of correlation ids, who creates them? Is it the client who issues a command, like PlaceOrder(order_id, correlation_id)? Is it the Aggregate that accepts the command like PlaceOrder(order_id) and then emits OrderCreated(order_id, corr_id) event? Or, is it the process manager (in some way) that is responsible for this? Alternatively, perhaps correlation ids have nothing to do with this?
在这种情况下,我不会使用关联 ID。我仅将它们用于调试目的。 在我的架构中,为了消除代码重复,相关ID由命令的创建者(在Saga中)或由CommandDispatcher
(如果这是进程中的第一个命令,所有 Commands
不是由 Sagas
生成的),并在生成的事件中存储为 Metadata
.
更新:
如何使用关联 ID?您 select 事件存储中具有该关联 ID 的所有事件,这样您就可以 "see" 处理。
强烈建议通过 Process Manager design pattern as well as @Vaughn Vernon treatment of the topic in his great book Implementing Domain-Driven Design
的原始来源
简而言之,Process Manager 通过在特定流程启动时创建的 Process 实例并发处理多个流程。 Process 实例的 ID 是您的 Correlation Identifier,它是流程持续时间内每次通信 (commands/events) 的有效负载的一部分。 Process instance还有一个术语,就是Process Tracker。思路是一样的。
因此,在这种方法中,存在明确的关注点分离。每个流程实例在其当前状态、重试、完成等方面负责其自己的流程。它是负责发出 ProcessFinished 事件的流程实例,因为它是 "brain".
流程管理器的另一个名称是长 运行 流程。所以根据定义,最好是异步的。
~谢尔盖
<><
我将 流程管理员 视为我领域中的第一个 class 公民。流程管理器实例的 Id
通常充当关联 ID。由于流程管理器是一个状态机,它实际上可以发布事件。好吧,我认为 Domain Events 不同于 System Events。消息传递基础结构依赖于 System Events。这些是携带相关 ID 的,是的,它会被复制到相关消息中,但这是您的基础设施可以自动执行的操作。在我的 Shuttle.Esb 服务总线中,我就是这样做的:复制 headers 和关联 ID。
这就是为什么我也将事物的过程方面视为几乎是一种 BC 本身。它通过发出命令然后响应相关事件与构成流程一部分的各种 BC 进行交互。但在基础设施(端点)层上,我可能想发布一个事件,说明某个特定流程已被放弃或完成或从一个步骤移至下一个步骤。
编辑:
在我看来,进程管理器本身也是一个集合体。所有命令和事件都将来自消息处理程序/应用程序层,以响应域中发生的事情。 do 来自领域的任何事件,就其本质而言,都是领域事件,这些事件不一定适合系统到系统的通信。我想说 "on the integration / application layer" 比基础设施(端点)层更合适。
所有消息都在消息处理程序中处理。该消息处理程序充当集成点,必须直接或通过应用层与域交互。我的措辞可能没有表现得那么明显:)
免责声明:由于您提到的示例交替使用了 "saga" 和 "process manager" 术语,因此我也会这样做。我确实知道 saga 和流程管理器模式在定义上是不同的,但在行业中我们看到 saga 这个词被许多流行的框架(从 NServiceBus 开始)应用。
查看这个特定示例,它将是:
从传奇中发布事件:视情况而定。我强烈警告您不要对谁可以做什么建立任何教条式的方法。你永远不会知道第二天会发生什么,你不应该什么都做 "by the book"。如果 ProcessManager 协调整个过程,它很可能会从一个聚合或上下文中使用 OrderConfirmed
事件,将命令发送到下一步,等待它产生确认事件,并在整个过程完成时 -发出自己的事件,在这种情况下,它通过某种 UI 魔法发送给客户。在这种方法中,我没有看到任何错误。不过可能会有更好的解决方案。
通常,saga id == correlation id 并且它要么是一些人为的短命识别,在这种情况下,您确实需要跟踪相关性,要么依靠您的基础设施来传递它从命令到命令处理程序端的事件。一旦创建了 saga 实例,您将需要生成这样的 id(请记住,saga 具有逻辑和状态,并且每个 运行 进程都有自己的状态)。或者您可以使用一些域对象 ID,就像您所指的情况一样,这可能是订单 ID。尽管如此,您仍需要注意将相关 ID 从命令传递到命令处理程序端的事件。所以,saga id == correlation id == process state id,也经常作为saga状态持久化的主键。
您还可以在 Chris Patterson's blog post.
中找到一篇关于使用状态机和 MassTransit 框架实现长期 运行 流程的好博客 post
进程管理器是否使用相关 ID 或聚合特定标识来跟踪它正在管理的 进程?
为了更清楚地举个例子,请考虑 Saga on Sagas 上的图 2:
首先,Process Manager 发送 OrderConfirmed
事件是错误的,对吧?我(作为流程管理者)不能发送事件,只能发出命令。还是我错了?
其次,流程管理器如何关联来自不同聚合的 OrderCreated、SeatsReserved、PaymentReceived 事件?它是每个聚合荣誉(并复制)的相关 ID,还是特定标识符(例如,SeatsReserved 有一个引用订单聚合的订单 ID)?
最后,如果是关联 ID,谁 创建 它们?是客户端发出命令,比如PlaceOrder(order_id, correlation_id)
?是 Aggregate 接受像 PlaceOrder(order_id)
这样的命令然后发出 OrderCreated(order_id, corr_id)
事件吗?或者,是流程经理(以某种方式)对此负责吗?或者,也许相关 ID 与此无关?
感谢您的帮助。
首先我要说我的回答基于我的知识、经验和我对如何在 PHP
上执行 CQRS 的看法First of all, Process Manager sending a OrderConfirmed event is wrong right? I (as a process manager) cannot send events, only issue commands. Or am I wrong?
是的。这是错误的。只有 Aggregates
引发 Domain Events
并执行 Commands
。也许 Microsoft 忘记显示发送到 OrderAggregate
.
MarkOrderAsConfirmed command
Second, how does the process manager correlate the OrderCreated, SeatsReserved, PaymentReceived events from different aggregates? Is it correlation id that each aggregate honors (and copies over), or is it specific identifiers (e.g. SeatsReserved has an Order Id that refers to the Order Aggregate)?
我使用参与该过程的 Aggregates
的 ID。本例中的关联 ID 与 OrderAggregate
的 ID 一对一映射,具有相同的生命周期。
Finally, if it is the case of correlation ids, who creates them? Is it the client who issues a command, like PlaceOrder(order_id, correlation_id)? Is it the Aggregate that accepts the command like PlaceOrder(order_id) and then emits OrderCreated(order_id, corr_id) event? Or, is it the process manager (in some way) that is responsible for this? Alternatively, perhaps correlation ids have nothing to do with this?
在这种情况下,我不会使用关联 ID。我仅将它们用于调试目的。 在我的架构中,为了消除代码重复,相关ID由命令的创建者(在Saga中)或由CommandDispatcher
(如果这是进程中的第一个命令,所有 Commands
不是由 Sagas
生成的),并在生成的事件中存储为 Metadata
.
更新: 如何使用关联 ID?您 select 事件存储中具有该关联 ID 的所有事件,这样您就可以 "see" 处理。
强烈建议通过 Process Manager design pattern as well as @Vaughn Vernon treatment of the topic in his great book Implementing Domain-Driven Design
的原始来源简而言之,Process Manager 通过在特定流程启动时创建的 Process 实例并发处理多个流程。 Process 实例的 ID 是您的 Correlation Identifier,它是流程持续时间内每次通信 (commands/events) 的有效负载的一部分。 Process instance还有一个术语,就是Process Tracker。思路是一样的。
因此,在这种方法中,存在明确的关注点分离。每个流程实例在其当前状态、重试、完成等方面负责其自己的流程。它是负责发出 ProcessFinished 事件的流程实例,因为它是 "brain".
流程管理器的另一个名称是长 运行 流程。所以根据定义,最好是异步的。
~谢尔盖
<><
我将 流程管理员 视为我领域中的第一个 class 公民。流程管理器实例的 Id
通常充当关联 ID。由于流程管理器是一个状态机,它实际上可以发布事件。好吧,我认为 Domain Events 不同于 System Events。消息传递基础结构依赖于 System Events。这些是携带相关 ID 的,是的,它会被复制到相关消息中,但这是您的基础设施可以自动执行的操作。在我的 Shuttle.Esb 服务总线中,我就是这样做的:复制 headers 和关联 ID。
这就是为什么我也将事物的过程方面视为几乎是一种 BC 本身。它通过发出命令然后响应相关事件与构成流程一部分的各种 BC 进行交互。但在基础设施(端点)层上,我可能想发布一个事件,说明某个特定流程已被放弃或完成或从一个步骤移至下一个步骤。
编辑:
在我看来,进程管理器本身也是一个集合体。所有命令和事件都将来自消息处理程序/应用程序层,以响应域中发生的事情。 do 来自领域的任何事件,就其本质而言,都是领域事件,这些事件不一定适合系统到系统的通信。我想说 "on the integration / application layer" 比基础设施(端点)层更合适。
所有消息都在消息处理程序中处理。该消息处理程序充当集成点,必须直接或通过应用层与域交互。我的措辞可能没有表现得那么明显:)
免责声明:由于您提到的示例交替使用了 "saga" 和 "process manager" 术语,因此我也会这样做。我确实知道 saga 和流程管理器模式在定义上是不同的,但在行业中我们看到 saga 这个词被许多流行的框架(从 NServiceBus 开始)应用。
查看这个特定示例,它将是:
从传奇中发布事件:视情况而定。我强烈警告您不要对谁可以做什么建立任何教条式的方法。你永远不会知道第二天会发生什么,你不应该什么都做 "by the book"。如果 ProcessManager 协调整个过程,它很可能会从一个聚合或上下文中使用
OrderConfirmed
事件,将命令发送到下一步,等待它产生确认事件,并在整个过程完成时 -发出自己的事件,在这种情况下,它通过某种 UI 魔法发送给客户。在这种方法中,我没有看到任何错误。不过可能会有更好的解决方案。通常,saga id == correlation id 并且它要么是一些人为的短命识别,在这种情况下,您确实需要跟踪相关性,要么依靠您的基础设施来传递它从命令到命令处理程序端的事件。一旦创建了 saga 实例,您将需要生成这样的 id(请记住,saga 具有逻辑和状态,并且每个 运行 进程都有自己的状态)。或者您可以使用一些域对象 ID,就像您所指的情况一样,这可能是订单 ID。尽管如此,您仍需要注意将相关 ID 从命令传递到命令处理程序端的事件。所以,saga id == correlation id == process state id,也经常作为saga状态持久化的主键。
您还可以在 Chris Patterson's blog post.
中找到一篇关于使用状态机和 MassTransit 框架实现长期 运行 流程的好博客 post