事件驱动架构实践:从同步调用到异步事件流

事件驱动架构用领域事件连接服务,降低同步耦合,但也带来了事件版本、最终一致、可观测性和治理问题。

事件驱动架构实践:从同步调用到异步事件流

事件驱动架构的核心是:服务不直接命令所有下游做事,而是发布“已经发生的事实”。

订单服务不说“库存服务扣库存、积分服务加积分、通知服务发短信”,而是发布 OrderPaid。下游系统根据自己的职责订阅事件。

Rendering diagram...

命令和事件

命令表示“请你做某事”,比如 CreateOrder

事件表示“某事已经发生”,比如 OrderCreated

事件驱动架构应该尽量发布事实,而不是把事件变成远程命令。

领域事件

领域事件来自业务模型。常见事件包括:

  • OrderCreated
  • OrderPaid
  • OrderCancelled
  • PaymentSucceeded
  • InventoryReserved
  • RefundCompleted

事件名要稳定,语义要清晰。不要用 OrderUpdated 这种过于模糊的事件承载所有变化。

事件版本

事件一旦被多个系统消费,就不能随意改字段。

可以在事件里加入版本:

{
  "event_type": "OrderPaid",
  "event_version": 2,
  "event_id": "evt_10001",
  "payload": {
    "order_id": "10001",
    "pay_amount": 199.00
  }
}

新增字段通常兼容,删除字段和改字段类型风险很高。

CQRS 和 Event Sourcing

CQRS 把写模型和读模型分开。写侧处理命令和事务,读侧通过事件构建查询模型。

Event Sourcing 则更进一步,把事件作为事实来源,通过重放事件恢复状态。

这两种模式很强,但复杂度也高。普通业务系统不一定需要完整 Event Sourcing,但可以借鉴“事件驱动读模型”的思想。

事件驱动的代价

事件驱动降低同步耦合,但带来新的复杂度:

  • 最终一致。
  • 消息重复。
  • 消息乱序。
  • 事件版本治理。
  • 链路追踪困难。
  • 问题排查跨多个服务。

因此事件驱动系统必须配套可观测性:trace id、event id、消费日志、死信队列、重放工具。

小结

事件驱动架构适合服务多、流程长、下游多的系统。它让核心服务只发布事实,让下游独立演进。

但事件驱动不是简单“加个 MQ”。它需要事件建模、版本治理、幂等消费、最终一致和可观测性一起落地。

参考链接