发布日期

事件溯源模式(Event-Sourcing)在项目中的应用

我为什么去使用 Event-Sourcing

最近几个月,我在开发中接触到了领域驱动设计(DDD)。在接触的过程中,我觉得这些理念是和我们传统的 CRUD 的开发是完全不一样的。里面就涉及了 TDD 以及 Event-Sourcing 这些东西去辅助我们的 DDD 开发。在开发过程中,对比传统 CRUD 有它的优点以及缺点。当然这些不再我们此次讨论的范围。我只是将其中涉及 DDD 以及 Event-Sourcing 的业务给大家分享下。

需求

假设我们需要做一个类似滴滴的平台。其中一个需求是这样的,用户可以预定车辆,当车辆被预订的时候,不能再被其他人在预定。

  • 传统做法

  • Event-Sourcing 做法

  • 当我们使用 Event-Sourcing 做法进行预定和结束的时候得到的事件数据(假设订单对应的唯一的 aggregate_uuid 为 8170ed30-c326-4268-ad04-f5d9380c481d,车辆的对应的唯一的 aggregate_uuid 为 d71d0d82-6230-4646-b0c4-40b84fce3e82)

    id aggregate_uuid event_class event_properties created_at
    1 8170ed30-c326-4268-ad04-f5d9380c481d OrderReserved {"userId": 8, "vehicleId": 2, "reserveTime": {"to": "2021-02-10T18:00:00+08:00", "from": "2021-02-10T17:45:00+08:00", "requestTime": "2021-02-10T12:26:11+08:00"}} 2021-02-10 12:26:11
    2 d71d0d82-6230-4646-b0c4-40b84fce3e82 OccupiedByReserve {"bookingAggregateId": "8170ed30-c326-4268-ad04-f5d9380c481d"} 2021-02-10 12:26:20
    3 8170ed30-c326-4268-ad04-f5d9380c481d OrderFinished {"userId": 8, "vehicleId": 2, "finishTime": {"to": "2021-02-10T18:00:00+08:00", "from": "2021-02-10T17:45:00+08:00", "requestTime": "2021-02-10T12:26:25+08:00"}} 2021-02-10 12:26:25
    4 d71d0d82-6230-4646-b0c4-40b84fce3e82 WentVacantByFinish {"bookingAggregateId": "8170ed30-c326-4268-ad04-f5d9380c481d"} 2021-02-10 12:26:28
  • 根据上述案例的事件进行逻辑判断

    判断车辆是否可用

案列延伸

假如用户预定车辆,消费钱包金额,充值给钱包增加一定金额。当我们要统计用户余额的时候我们可以用下面方法。

  • 假设用户 User 表对应一个 aggregate_uuid 1b2f273a-8aed-43dc-8d05-a708a9a0a09c
  • 充值的时候增加一个事件 TopUp,记录的充值的金额,时间等相关信息。
  • 用户完成预定的时候增加一个事件 OrderFeeDebited, 记录的订单的金额,时间等相关信息。

优点

  • 方便进行溯源与历史重现
  • 方便 Bug 的修复
  • 方便使用数据分析等系统

缺点

  • 性能问题
  • 事件维护麻烦。(比如 TopUp 事件里面的数据字段有变更,将非常麻烦,当前做法是新建一个 TopUpV2 事件,两者的区别可能仅仅只是多了一个属性,相关的调用的地方也得改为调用 TopUpV2)

参考资料

声明

备案号:湘ICP备2020019075号 © 2020 yxx All rights reserved. | my github