领域事件
领域事件和事件总线
An event is something that has happened in the past. A domain event is, logically, something that happened in a particular domain, and something you want other parts of the same domain (in-process) or domain in aonther bounded context to be aware of and potentially react to.
领域事件是领域模型中非常重要的部分,用来表示领域中发生的事件。一个领域事件将导致进一步的业务操作,有助于形成完整的业务闭环。领域事件主要用于解耦微服务,各个微服务之间不再是强一致性,而是基于事件的最终一致性。

微服务内的领域事件可以通过事件总线或利用应用服务实现不同聚合之间的业务协同。当微服务内发生领域事件时,由于大部分事件的集成发生在同一个线程内,不一定需要引入消息中间件。但一个事件如果同时更新多个聚合数据,按照
事件构建
Your Domain Event type names should be a statement of a past occurrence, that is, a verb in the past tense.
因为表示的是过去事件,所以推荐命名为
CustomerCreatedEvent, 表示客户创建后发出的领域事件。- OpportunityTransferedEvent,表示机会转移后发出的领域事件。
- LeadsCreatedEvent,表示线索创建后发出的领域事件。
- Enrichment:也就是在
Event 的payload 中尽量多多放data ,这样consumer 就可以自恰(Autonomy)的处理消息了。 - Query-Back:这种是在
Event 中通过回调拿到更多的data ,这种形式会加重系统的负载,performance 也会差一些。
所以如果要在
事件总线
事件总线位于基础层,为应用层和领域层服务提供事件消息接收和分发等服务。其大致流程如下:服务触发并发布事件、事件总线事件分发。
-
如果是微服务内的订阅者(微服务内的其它聚合
) ,则直接分发到指定订阅者。 -
如果是微服务外的订阅者,则事件消息先保存到事件库(表)并异步发送到消息中间件。
-
如果同时存在微服务内和外订阅者,则分发到内部订阅者,并将事件消息保存到事件库(表)并异步发送到消息中间件。为了保证事务的一致性,事件表可以共享业务数据库。也可以采用多个微服务共享事件库的方式。当业务操作和事件发布操作跨数据库时,须保证业务操作和事件发布操作数据的强一致性。
事件数据持久化与溯源
事件数据的持久化存储可以有两种方案,在项目实施过程中根据具体场景选择最佳方案。
- 事件数据保存到微服务所在业务数据库的事件表中,利用本地事务保证业务操作和事件发布操作的强一致性。
- 事件数据保存到多个微服务共享的事件库中。需要注意的一点是:这时业务操作和事件发布操作会跨数据库操作,须保证事务的强一致性(如分布式事务机制
) 。
事件数据的持久化可以保证数据的完整性,基于这些数据可以完成跨微服务数据的一致性比对。
使用
Event Sourcing 存储了所有发生在Core Domain 上面的事件。- 基于这些事件,我们可以做系统回放,系统
Debug ,以及做用户行为的分析(类似于打点)