4. 事件风暴画布设计:画布结构设计、领域事件识别与建模、命令与聚合映射、边界上下文划分

事件风暴(Event Storming)是一种协作建模技术,用于快速探索复杂业务领域并生成统一的领域语言。在分布式事务场景中,事件风暴画布是连接业务需求与技术实现的桥梁。本节将围绕画布结构、领域事件识别、命令与聚合映射以及边界上下文划分四个核心环节展开,确保团队能够从业务事件出发,逐步推导出可落地的微服务架构与事务边界。

4.1 画布结构设计:四层协作空间

事件风暴画布通常采用“时间轴 + 泳道”的二维结构。为适应分布式事务的复杂性,我们将其扩展为四层协作空间,每一层承载不同粒度的建模元素。

画布层级 核心元素 颜色标识 建模目的
业务时间轴 领域事件(Domain Event) 橙色便签 按时间顺序记录业务中发生的关键事实
命令层 命令(Command) 蓝色便签 触发领域事件的用户意图或系统请求
聚合层 聚合(Aggregate) 黄色便签 封装业务不变性,响应命令并产生事件
边界上下文层 限界上下文(Bounded Context) 灰色/透明框 划分模型边界,定义上下文映射关系
实践建议: 在分布式事务项目中,建议使用物理白板或 Miro 等数字工具,按“事件→命令→聚合→上下文”的顺序逐层填充。避免一开始就讨论数据库表结构或 API 设计,保持业务语言主导。

4.2 领域事件识别与建模

领域事件是事件风暴的起点,表示业务领域中已经发生的、不可改变的事实。在分布式事务场景中,领域事件通常对应跨服务的数据变更或状态转移。

4.2.1 识别领域事件的“五问法”

  1. 业务发生了什么? 例如:“订单已创建”、“支付已成功”。
  2. 谁关心这件事? 识别事件的消费者(其他聚合或服务)。
  3. 事件发生后,系统状态如何变化? 明确事件携带的数据字段。
  4. 事件是否具有事务一致性要求? 判断是否需要强一致性或最终一致性。
  5. 事件是否会被重放或补偿? 为后续的 Saga 或事件溯源做准备。

4.2.2 领域事件建模规范

每个领域事件应使用“名词 + 动词过去式”的命名方式,并附带时间戳和唯一标识。以下是一个典型的领域事件结构示例:

{
  "eventId": "evt_20250321123456_001",
  "eventType": "OrderCreated",
  "timestamp": "2025-03-21T12:34:56.789Z",
  "source": "order-service",
  "payload": {
    "orderId": "ord_98765",
    "customerId": "cust_12345",
    "totalAmount": 299.99,
    "items": [
      { "productId": "prod_001", "quantity": 2, "price": 149.995 }
    ]
  }
}
关键原则: 领域事件必须是过去时态,且不可变。一旦发布,不应被修改,只能通过新事件进行补偿或修正。

4.3 命令与聚合映射

命令是用户或外部系统发起的意图,聚合是响应命令并产生事件的业务一致性边界。在分布式事务中,一个命令可能跨多个聚合执行,此时需要引入 Saga 或 TCC 模式来协调。

4.3.1 命令到聚合的映射矩阵

命令名称 触发角色 目标聚合 产生的领域事件 事务模式
CreateOrder 用户 订单聚合 OrderCreated 本地事务
SubmitPayment 支付网关 支付聚合 PaymentSubmitted 本地事务
ConfirmOrder 支付聚合 订单聚合 OrderConfirmed Saga 协调
ReserveInventory 订单聚合 库存聚合 InventoryReserved TCC Try

4.3.2 聚合设计原则

  • 一致性边界: 一个聚合内的所有状态变更必须在同一个本地事务中完成。
  • 单一职责: 每个聚合只负责一个明确的业务概念,例如“订单聚合”不直接管理支付状态。
  • 事件驱动: 聚合通过发布领域事件通知其他聚合或服务,避免直接远程调用。
常见陷阱: 不要将多个聚合合并为一个“大聚合”来避免分布式事务。这会导致聚合臃肿、性能下降,并破坏领域模型的清晰性。正确的做法是通过 Saga 或事件驱动来协调跨聚合的事务。

4.4 边界上下文划分

限界上下文是 DDD 中最重要的战略设计工具。在分布式事务项目中,每个限界上下文通常对应一个独立的微服务或模块,拥有自己的数据存储和事务边界。

4.4.1 划分依据

  1. 业务语言一致性: 同一上下文中使用统一的术语和规则。
  2. 事务边界: 强一致性需求应限制在同一个上下文内。
  3. 变更频率: 经常一起变更的聚合应放在同一上下文中。
  4. 团队结构: 遵循康威定律,每个上下文可由一个独立团队维护。

4.4.2 上下文映射关系

在事件风暴画布中,使用灰色框圈定每个限界上下文,并在上下文之间绘制映射关系。常见的映射模式包括:

映射模式 描述 适用场景
合作关系(Partnership) 两个上下文相互依赖,需同步协调 订单与支付上下文
防腐层(Anti-Corruption Layer) 下游上下文隔离上游模型的变更 遗留系统集成
开放主机服务(OHS) 上下文对外发布标准事件或API 事件总线集成
共享内核(Shared Kernel) 两个上下文共享部分领域模型 高度耦合的模块

4.5 事件风暴画布整体结构图

以下 SVG 图展示了事件风暴画布的四层结构,以及领域事件、命令、聚合和限界上下文之间的典型关系。该图可作为团队协作建模时的参考模板。

事件风暴画布四层结构(分布式事务版) 业务时间轴(领域事件) 订单已创建 支付已提交 库存已预留 订单已确认 命令层(Command) CreateOrder SubmitPayment ReserveInventory ConfirmOrder 聚合层(Aggregate) 订单聚合 (Order Aggregate) 支付聚合 (Payment Aggregate) 库存聚合 (Inventory Aggregate) 边界上下文层(Bounded Context) 订单上下文 (Order Context) 支付上下文 (Payment Context) 库存上下文 (Inventory Context) 说明: 1. 橙色节点为领域事件,按时间轴从左到右排列。 2. 蓝色命令触发橙色事件,黄色聚合响应命令,紫色框定义服务边界。

4.6 实战案例:订单履约流程的事件风暴建模

以一个典型的电商订单履约流程为例,展示从事件识别到上下文划分的完整过程。

4.6.1 步骤一:列出关键领域事件

  • OrderPlaced(订单已下单)
  • PaymentReceived(支付已收到)
  • InventoryAllocated(库存已分配)
  • OrderShipped(订单已发货)
  • OrderDelivered(订单已送达)

4.6.2 步骤二:为每个事件补充命令和聚合

领域事件 触发命令 所属聚合 限界上下文
OrderPlaced PlaceOrder 订单聚合 订单上下文
PaymentReceived ProcessPayment 支付聚合 支付上下文
InventoryAllocated AllocateInventory 库存聚合 库存上下文
OrderShipped ShipOrder 物流聚合 物流上下文

4.6.3 步骤三:绘制上下文映射关系

在事件风暴画布上,使用灰色框圈定四个上下文,并在它们之间绘制事件流。例如:

  • 订单上下文发布 OrderPlaced 事件,支付上下文订阅后执行 ProcessPayment。
  • 支付上下文发布 PaymentReceived 事件,订单上下文和库存上下文同时订阅。
  • 库存上下文发布 InventoryAllocated 事件,订单上下文更新状态为“可发货”。
核心产出: 通过事件风暴画布,团队可以直观地看到跨上下文的事务依赖关系,从而决定哪些环节需要引入 Saga 或 TCC 模式来保证最终一致性。

4.7 本章小结

事件风暴画布设计是分布式事务项目从业务分析走向技术落地的关键桥梁。通过四层画布结构,团队能够系统性地识别领域事件、映射命令与聚合、划分限界上下文,并最终形成清晰的微服务边界和事务协调策略。下一阶段将基于此画布进行服务拆分与接口设计。