3

我正在尝试使用 dddd 实现事件源系统。目前,我正在为我的事件如何以及在何处跨越有界上下文的边界而苦苦挣扎。

想象有两个有界上下文:

  1. 产品管理
  2. 物流系统

产品管理拥有关于产品的所有知识。为简单起见,它只是“名称”。物流系统也有产品,但对它们的元数据一无所知。对他们来说,它主要是一个带有 ID 的物理盒子。但是当有人扫描这个产品时,他们也想显示名称。因此,ProductManagement BC 应该通知 Logistics BC,产品已注册并且名称已更改。因此,我将以 ProductManagement 中的事件结束,这些事件是从 ProductAggregate 内部引发的:

ProductManagement.Events.ProductRegistered
ProductManagement.Events.ProductNameChanged

当我正确理解这些是我将保存到事件存储中的事件。这些也是将发布到消息总线中的事件。所以在物流方面,我会订阅这些活动。到目前为止,一切都很好。

现在的问题是:我将如何在物流方面处理这个事件?Vaughn Vernon 在一次演讲中说,最好的做法是在应用层有一个事件处理程序,所以它基本上是一个应用程序服务。他还说,最好将其转换为一个或几个命令。我是否再次将所有收到的事件保存在物流端?我还要保存命令吗?如果出现问题,如何重现当前状态?或者我怎么知道,这不是接收限界上下文中处理的错误,而是错误的事件。如果我的转换命令被拒绝,我该怎么办?

我知道物流方面的总量没有计算或变化。但我认为这对我的问题并不重要。

4

3 回答 3

1

这里有几件事。

首先,您不必导入 Logistics BC 关于名称更改。您可以在需要时从客户那里从 PM BC 获取此信息。这通常由某种复合 UI 完成。UI 组合可以在客户端或(Web)服务器上完成。您可能想查看Mauro Servienti撰写的文章The secret of better UI composition对此进行了描述。

但总的来说,这通常是这样的:

domain event -> pub/sub -> message consumer -> command -> domain command handler

所以,

  1. 您从 PM BC 将域事件发布到总线
  2. 物流中有此事件的事件处理程序
  3. 事件处理程序可能会做一些检查,并将RegisterProduct命令发送到同一个 BC
  4. 该命令照常处理,并Product在后勤系统中创建新聚合

它不仅在事件源系统中如此工作,而且在使用事件驱动架构的任何具有多种服务的系统中都是如此。

于 2017-01-25T19:26:45.390 回答
0

[...] 他还说,最好将其转换为一个或多个命令。我是否再次将所有收到的事件保存在物流端?我还要保存命令吗?

首先,您必须询问领域专家该事件是否会导致影响 LS 上下文的副作用。只有在这种情况下,您必须订阅此事件并将相关命令发送到将更改并提交其状态的 LS 聚合,或者,如果您也选择事件源此聚合,则发送另一个事件。

如果出现问题,如何重现当前状态?或者我怎么知道,这不是接收限界上下文中处理的错误,而是错误的事件?如果我的转换命令被拒绝,我该怎么办?

事件是发生的事情的表示,所以它不能是“错误的”。无论如何,由事件触发的命令可能会失败。你说的是哪种类型的失败?技术或特定领域?在第一种情况下,源事件将留在总线中以供将来重试(可能在一些错误修复之后)。在第二种情况下,如果需要通知 PM 聚合结果,则 LS 聚合应发出适当的事件,该事件反过来将由 PM 聚合处理。

于 2017-01-27T15:06:57.127 回答
0

对于您描述的用例,您只需要物流系统使用的产品的一些属性。因此,物流系统可以通过订阅您描述的事件来保存它需要的产品信息的本地缓存——这可能是一个简单的内存缓存。当您处理读取模型即 A 视图时,它们不需要转换为命令或类似的东西。只需让一个简单的事件处理程序处理事件并在某处更新某些状态 - 无需在读取端对其进行事件源。当物流系统需要产品名称时,它只是从本地缓存中获取。你没有打破这两种环境的自主性,因为产品管理仍然是事实的来源。

如果您需要重建状态,您只需擦除缓存并通过处理程序重播所有事件。但是请记住,产品管理上下文拥有这些事件,因此它们应该只保存在那里,而不是在物流上下文中 - 如果您想要重建状态,您将需要一种重新发布它们的方法

顺便说一下,这一系列博客文章描述了这个确切的用例:

https://www.tigerteam.dk/2014/micro-services-its-not-only-the-size-that-matters-its-also-how-you-use-them-part-1/

(如果我没记错的话,在第 5 部分)

或者,您可以进行某种 UI 组合,其中名称取自产品管理上下文,其他详细信息取自物流上下文(也在上述博客文章中讨论)

于 2017-01-25T19:29:50.613 回答