0%

如何用事件溯源模式设计一个系统

事件溯源模式用于设计一个具有确定性的系统,这改变了普通系统设计的理念。我们通过一个电商系统来演示一下普通的 CRUD 和事件溯源模式的区别。

事件溯源模式不是在数据库中记录订单状态,而是将导致状态变化的事件保存在事件存储中,事件存储是一个仅附加的日志,类似于数据库中的 undo log。

事件必须有递增的主键 ID,以保证其顺序。订单状态通过回放事件来构建,并在订单视图(OrderView)中维护。如果订单视图发生故障,我们总是可以依赖事件存储进行修正,它是恢复订单状态的真实来源。

让我们来看看详细的步骤。

非事件溯源模式

20220722094137.png

  • 步骤 1 和 2:Bob 想买一个产品,订单被创建并插入到数据库中。
  • 步骤 3 和 4:Bob 想把数量从 5 改为 6。该订单被修改为新的状态。
  • 步骤 5 和 6:Bob 为该订单支付了 6 元,订单完成,状态改为已支付(PAID)。
  • 步骤 7 和 8:Bob 查询最新的订单状态,查询服务从数据库中检索状态。

事件溯源

20220722094154.png

  • 步骤 1 和 2:Bob 想买一个产品:一个 NewOrderEvent 被创建,按序存储在事件仓库中,此时 eventID=2001。
  • 步骤 3 和 4:Bob 想把商品数量从 5 改为 6:一个 ModifyOrderEvent 被创建,并以 eventID=2002 的形式按序保存在事件仓库中。
  • 步骤 5 和 6:Bob 为这个订单支付了 60 元:一个 OrderPaymentEvent 被创建,并以 eventID=2003 的形式存储在事件仓库中。注意不同的事件类型有不同的事件属性。
  • 第 7 步:订单视图(OrderView)监听从事件仓库中发布的事件,并建立订单的最新状态。虽然订单视图收到了 3 个事件,但是它一个一个按序应用这些事件,并保持订单最新的状态。
  • 第 8 步:Bob 从订单服务(OrderService)查询订单状态,订单服务可以通过订单视图(OrderView)来获取订单状态。
    • 订单视图可以在内存或缓存中,不需要被持久化,因为它可以从事件存储中恢复。
    • 订单视图表也可以持久化到其他数据库引擎中,如 ElasticSearch 来支持订单搜索,这就用到了另一种模式:CQRS。