我是新手EDA,已经阅读了许多关于其优点的内容,可能会在我的下一个项目中应用它,但仍然有些不理解。
在引发事件时,哪种模式最适合:
- 将事件命名为"CustomerUpdate",并包括客户的所有信息(已更新或未更新)
- 将事件命名为"CustomerUpdate",并只包括真正被更新的信息
- 将事件命名为"CustomerUpdate",并包括最少的信息(标识符)和/或URI,以便使用者检索有关此客户的信息。
我提出这个问题是因为我们的一些事件可能很重,而且频繁。
感谢您的回答和时间。
我是新手EDA,已经阅读了许多关于其优点的内容,可能会在我的下一个项目中应用它,但仍然有些不理解。
在引发事件时,哪种模式最适合:
我提出这个问题是因为我们的一些事件可能很重,而且频繁。
感谢您的回答和时间。
Name the event "CustomerUpdate"
首先,让我们从事件名称开始。事件的目的是描述已经发生的事情。这与命令不同,命令是为尚未发生的事情下达指令。
您的事件名称“CustomerUpdate”在这方面听起来有些模糊,因为它可能描述过去或未来的事情。
“CustomerUpdated”会更好一些,但即使如此,“Updated”也是另一个模糊的术语,在业务环境中没有具体含义。在这种情况下,客户是否更新了他们的付款信息?搬家了吗?升级到白金会员?事件可以根据需要变得具体。
这一点乍一看可能会被认为是过于深思熟虑,但随着您从事件负载中删除数据和上下文,并向着“skinny”事件(您问题中的“选项3”,我将在下面讨论)转移,事件命名变得尤为重要。
这并不意味着总是适合以这种细粒度定义事件,只是在项目早期就打开了这条路,后期可能会带来回报(或者可能会给您带来数千个事件类型)。
回到你实际的问题,让我们依次看看你的每个选项:
将事件命名为“CustomerUpdate”,并包括有关客户的所有信息(已更新或未更新)
让我们称这种“模式”为 Fat 消息。
Fat消息(也称为快照)表示在给定时间点上所描述实体的状态,并且负载中包含所有事件上下文。它们很有趣,因为消息本身代表服务和消费者之间的契约。它们可用于在业务领域之间通信状态更改,在此期间可能希望在消费者的消息处理期间存在所有事件上下文。
优点:
缺点:
将事件命名为“CustomerUpdate”,并仅包括确实已更新的信息
让我们称这种模式为Delta消息。
在许多方面,Delta与Fat消息类似,但它们通常更复杂,难以生成和消费。这里有一个很好的例子,即JSONPatch标准。
由于它们只是事件实体的部分描述,因此Delta还带有一种内置假设,即使用者了解所描述的事件。因此,它们可能不太适合发送到业务领域之外,在那里事件实体可能不为人所知。
当在共享相同实体模型的系统之间同步数据时,Delta真正发挥作用,理想情况下,该模型存储在非关系型存储中(例如,无SQL)。在这种情况下,可以检索实体,应用Delta,然后再次进行持久化,而不需要太多的努力。
优点:
缺点:
将事件命名为“CustomerUpdate”,并包括最少信息(标识符)和/或URI,以便让使用者检索有关此客户的信息。
我们称之为瘦消息。
与您定义的其他消息模式不同,瘦消息的服务/使用者合同不再显式存在于消息中,而是暗示消费者将在稍后的某个时间检索事件上下文。这样可以将合同和消息交换分离开来,这是一件好事。
这可能适用于跨业务域事件通信,也可能不适用,具体取决于企业的设置方式。由于事件负载非常小(通常是带有一些标头的ID),因此除了事件名称外,消费者没有其他上下文可基于其进行处理决策; 因此,如果有多种方法可以处理CustomerUpdated消息,则更重要的是确保事件的名称适当命名。
此外,在事件数据中包含实际的资源地址可能不是一个好的做法,因为事件已经发生,事件消息通常是不可变的,因此事件中的任何信息应该永远是真实的,以防需要重播事件。在这种情况下,资源地址很容易变得过时,事件将无法被重播。评论更新:还值得一读的是一篇非常古老、经典的关于消息传递的博客文章:https://learn.microsoft.com/en-gb/archive/blogs/nickmalik/killing-the-command-message-should-we-use-events-or-documents(也可以在这里找到:http://vanguardea.com/killing-the-command-message-should-we-use-events-or-documents/)