我见过的大多数事件驱动重写,死的时候消息总线建好了80%,消费者有20%打了桩,困难问题一个没解决。我在其中两次死亡里是那个工程师。我也在一次真正交付的事件驱动现代化里是那个工程师,在 Bytro,历时两年。这篇文章是两种结果之间的差别,而那个差别和架构图说的无关。

关于事件驱动的安慰性谎言

那些演讲和博客文章让事件驱动听起来像一个模式:选一个消息中间件、定义事件、从写侧发出、在读侧投影、完事。工具到处都是。Apache Kafka、NATS、RabbitMQ、SQS——周末就能搭起基础设施。

这就是为什么重写会被启动。也是为什么它们会死去。

那个安慰性谎言是:架构是困难的部分。它不是。困难的部分是架构迫使你把所有隐式假设显式化。同步系统有大量隐式假设:请求顺序、事务边界、“这次写入对这次读取立即可见”、“如果 A 发生了,B 就完成了”。一旦你把读写分开,你同时也把所有这些假设分开——如果你不刻意解决它们,你的新系统就是一个旧系统的更差版本,还多了一个消息总线要运维。

Bytro 做对的事

在 Bytro,我们对一个多年成长为纠缠遗留系统的实时多人游戏后端进行了现代化。我们走向了事件驱动,它交付了,它成功了。原因如下:

1. 我们选了一个领域,而不是整个系统

诱惑是说”我们把事件驱动作为架构原则”。我们没有。我们选了一个具体的痛点——匹配加入 latency——然后说”这个流程将是第一个事件驱动的。其余的保持同步,直到另有证明。”

这意味着我们能在几个月而不是几年内交付第一个真实的事件驱动路径。也意味着所有其他团队的功能工作继续在旧系统上交付。现代化是一个服务,不是一次中断。

2. 我们影子运行了11个月

新路径从第四周起就在生产环境里——流量0%,对旧路径的每个请求做影子,产生不提供给用户但每晚和旧结果对比的结果。

差异就是规格。每一个”新系统产生了不同答案”都是新系统、旧系统或我们对领域理解的 bug。我们在那一年里修复了大约200个。每一个如果我们提前切换的话都会成为事故。

3. 我们保持事务边界的诚实

事件驱动不意味着”所有东西都是最终一致的,用户将就一下”。某些操作仍然必须是原子的。如果一个玩家加入一场匹配,三件事必须一起发生:玩家的状态更新、匹配的名单更新、计费钩子触发。这些不能是三个之间有祈祷的分离事件。

我们对这些使用了事务性 outbox 模式:写入发生在一个 DB 事务里,事件写入(到一个 outbox 表)同一个事务里,一个单独的进程稍后将事件发往总线。你在需要原子性的地方得到原子性,在不需要的地方得到异步交付。

每一个”我们不需要事务,我们是事件驱动的”对话都是一个等待发生的六个月灾难。保持你的事务边界明确且小。

4. 我们为还没建的消费者设计了事件

最困难的事件驱动决策是事件里放什么。太少,每个消费者都必须反向连接写侧 DB 来丰富负载(这败掉了重点)。太多,你把今天的 schema 烤进每个消费者的代码里,无法演进。

我们落地的规则:事件携带的最小负载,让一个合理的消费者无需往返就能渲染用户可见的结果。不是”写侧有的所有字段”。不是”就一个 ID”。介于两者之间的某处,而确切的形状是花了几个月才搞对的领域专属工作。

事件是公开契约。用你对待 REST API 的严肃性来对待事件 schema。版本化它。文档化它。以增量方式修改它。

5. 每一步都有回滚方案

第四周:功能开关关 → 回到100%旧路径。第十二周:开关关 → 回到旧路。第四十周:开关关 → 回到旧路。在任何时候,回滚都不超过一次配置变更,而且我们每月在真实演练中测试那个回滚。

在我们真正需要它的那天——第八个月,事件顺序里的一个边角案例——回滚花了两分钟。因为我们排练过。

杀死另外两次重写的东西

我看着死去的两次事件驱动现代化,大部分基础设施都就位了。中间件部署好了、topic 定义了、序列化器选好了。它们死在基础设施解决不了的事情上:

  • 没有影子。 它们在小流量上线然后寄希望于此。
  • 事务边界用”最终”来糊弄。 意思是:需要原子的操作变成了生产环境里的竞态条件。
  • 事件由委员会设计。 每个事件有40个字段,因为每个团队都想把自己的东西塞进去。结果是一个没人能订阅、不经过自己的预处理服务就无法解析的无差别数据流。
  • 没有回滚。 切换就是”拨动开关”。如果不成,就不成了。

所有四个失败都是组织和架构问题,不是基础设施问题。换一个不同的中间件解决不了任何一个。

2026年的补注

我当前大部分开源工作(Fulcrum)本身也以一种特定的方式是事件驱动的——agent 运行产生事件,这些事件流经一个记忆/任务/上下文总线。同样的规则在小规模上适用,就像在 Bytro 规模上一样:选一个流程、影子运行它、保持事务诚实、为消费者设计事件、排练回滚。

模式是不分规模的。有纪律是真正会规模化的那件事,不是中间件。