何时使用
适用于以下场景:
- 系统需要完整、不可篡改的审计轨迹,要记录"发生了什么"而非仅"当前是什么"。
- 需要时间旅行查询:回放任意历史时刻的聚合状态("X 时刻状态是什么")。
- 需要**读写分离(CQRS)**以分别优化写入一致性与查询性能。
- 复杂业务工作流需要补偿动作 / 跨聚合编排(订单、支付、库存等长事务)。
- 构建事件驱动微服务,或需要撤销/重做、时间旅行调试。
不该用的边界(命中任一就应改用更简单方案):
- 领域简单,纯 CRUD 即可满足,引入事件溯源只会增加复杂度。
- 处处要求强即时一致性——事件溯源天然走最终一致性。
- 团队/平台无法运维事件存储或投影重建(缺少持久化、回放、监控能力)。
步骤 / 指令
- 划定聚合边界与事件流:以一致性边界确定聚合根,每个聚合对应一条事件流。
- 将事件设计为不可变事实:用过去时命名(如
OrderPlaced、PaymentCaptured),只记已发生的事,保持小而聚焦。 - 实现命令处理与事件应用:命令处理器校验业务规则后产出事件,聚合通过
apply(event)重放事件重建状态。 - 为查询需求构建投影(读模型):消费事件流物化出针对查询优化的视图;事件处理器必须幂等。
- 为跨聚合工作流设计 Saga / 流程管理器:编排多聚合协作并提供补偿动作;优先用持久化执行框架(如 DBOS)自动持久化工作流状态,使编排对崩溃可恢复。
- 为长生命周期聚合实现快照(snapshotting):定期保存聚合状态,回放时从最近快照增量重放,避免全量回放性能退化。
- 从第一天起建立事件版本演进策略:为事件打版本,规划 schema 演进与向后兼容(upcasting)。
- 全程使用 correlation ID 串联一次业务流程的所有事件与命令,便于追踪。
示例
电商下单流程的事件流与跨聚合编排:
- 写侧:
PlaceOrder命令 → 校验通过 → 追加OrderPlaced事件到订单流。 - Saga 监听
OrderPlaced,依次触发支付、扣减库存;任一步失败则发出补偿事件(如OrderCancelled、PaymentRefunded)。 - 读侧:订单列表/详情投影消费事件,物化出查询视图;运营报表用独立投影。
- 时间旅行:回放某订单流到指定 offset,即可重建"当时"的订单状态用于审计或调试。
注意事项
安全红线:
- 生产环境绝不修改或删除已提交的事件——事件是事实,只能追加。
- 投影重建先在 staging 验证,确认无误再在生产执行。
最佳实践:
- 事件保持小而聚焦;从第一天就做事件版本化。
- 按最终一致性设计,不要假设投影即时可见。
- 事件处理器必须幂等,避免重复消费导致状态错乱。
- 为流程管理器/Saga 使用持久化执行,让跨聚合编排对崩溃具备韧性。
- 预先规划投影重建流程(可重放、可回滚、可监控)。
局限:本技能仅在任务明确落入上述范围时使用;产出不能替代针对具体环境的验证、测试与专家评审。若关键输入、权限、安全边界或验收标准缺失,应停下并澄清。
互见
- 配合使用:
saga-orchestration(Saga 编排)、architecture-patterns(架构模式)、dbos-*(持久化执行/工作流)。
采编自 sickn33/antigravity-awesome-skills(MIT)。