事件溯源

事件溯源是构建业务逻辑和持久化聚合的另一种选择。
通过聚合一系列事件的方式持久化保存。每个事件代表聚合的一次状态变化。应用程序通过重放来重新创建聚合的当前状态。

模式:事件溯源
使用一系列表示状态更改的领域事件来持久化聚合。

1. 传统持久化技术的问题

  • 对象和关系的“阻抗失调”
    关系型数据的表格结构模式,与领域模型及其复杂关系的图状结构之间,存在基本概念不匹配的问题。

  • 缺乏聚合的历史
    传统持久化的另一个限制是,它只存储聚合的当前状态。聚合更新后,其先前的状态将会丢失。
    如果应用程序必须保留聚合的历史,那么必须实现相应的业务逻辑。实现这个逻辑是非常耗时的一项工作,因为其中还有涉及到复制必须与业务逻辑保持一致的代码。

  • 实现审计功能非常繁琐且容易出错
    为了满足安全性或监管的要求,要实现审计功能以支持。
    挑战在于,除了这个是一个耗时的工作之外,负责审计日志的业务代码,可能与业务逻辑发生偏离,导致各种错误。

  • 事件发布凌驾于业务逻辑之上
    传统持久化的另一个限制是,它通常不支持发布领域事件。

2. 什么是事件溯源

事件溯源是一种以事件为中心的技术,用于实现业务逻辑和聚合的持久化。
事件溯源通过事件来持久化聚合
通过设置事件存储库(event表),结构如下:

evenv_idevent_typeentity_typeentity_idevent_data
101OrderCreatedOrder101{...}
102OrderApprovedOrder101{...}
103OrderShippedOrder101{...}
104OrderDeliveredOrder101{...}
...............

记录了Order变化的事件及所需的数据,通过加载事件存储库,可重放事件加载聚合。

  • 一般来说,按照以下步骤:
  1. 加载聚合事件列表
  2. 使用默认构造方法创建聚合实例
  3. 调用聚合事件相对应的apply方法,重放事件
  • 事件溯源常用实现如下:
  1. 使用process方法接受命令,返回事件列表
  2. 使用apply方法,接受事件,更新聚合

2.1 通过事件来持久化聚合

2.2 事件代表状态的改变

2.3 聚合方法都与事件相关

2.3.1 创建聚合的步骤如下:
  1. 使用聚合默认的构造函数实例化聚合根
  2. 调用process方法,生成事件列表1
  3. 遍历事件列表1,并调用apply方法更新聚合的状态
  4. 将事件列表保存至事件存储库
2.3.2 更新聚合的步骤如下:
  1. 从事件存储库加载事件列表1
  2. 使用其默认构造函数实例化聚合根
  3. 遍历加载的事件列表1,并在聚合根上调用apply方法
  4. 调用process方法以生成事件列表2
  5. 遍历事件列表2,并调用apply方法更新来聚合的状态
  6. 将新事件存储至事件存储库

2.4 并发更新

两个或多个请求同时更新同一聚合。
对于并发,避免问题出现的方式是,进行串行化的处理。

  • 对事件存储库新增一列,is_publish

    event_idis_publish
    1010
  • 将事件存储至事件存储库(即时),is_publish为0
  • 投递事件至消息代理
  • 将事件标记为已发布,is_publish=1
    事件执行反馈记录,这里不聊

2.5 领域事件的演化

事件溯源的结构分为三个层次:

  1. 由一个或多个聚合组成
  2. 定义每个聚合发出的事件
  3. 定义事件的结构

2.6 事件溯源的优劣

2.6.1 事件溯源的好处

可靠的发布领域事件
保留聚合的历史
最大程度的避免对象和关系的“阻抗失调”
为开发者提供一个时光机

2.6.2 事件溯源的弊端

编程模式有一定的学习曲线
基于消息传递的应用程序的复杂性
处理事件的演化有一定的难度
随着时间的推移,领域模型及结构都可能会有调整。

  1. 迁移旧结构,以支持当前最新的领域模型
  2. 代码中增加适配器,以兼容旧结构
    删除数据有一定的难度
  3. 事件溯源本身是要保留聚合的历史,永久的保存数据,所以传统的做法是进行软删除
  4. 使用软删除使用多种数据,但是根据欧洲的数据保护和隐私法规(GDPR),应用程序必须彻底删除用户的个人信息。
    做法是,通过用户设置UUID,根据UUID关联敏感数据。删除数据时,删除关联即可。
  5. 查询事件存储库非常有挑战性
    需要在事件存储库,找到没有直接搜索条件的数据。
    通过CQRS可实现该查询

2.7 通过快照来提高溯源的性能


冰茶么么哒
31 声望2 粉丝

« 上一篇
系统思维

引用和评论

0 条评论