事件驱动架构:真正重要的是边界
只有当归属、投递保证和恢复路径都被写清楚时,事件才会带来杠杆。
事件驱动架构常常以一张图的形式被介绍:左边是生产者,中间是消息中间件,右边是消费者。真正困难的部分,全在那些箭头没有说出来的地方。
事件是一份关于「过去」的契约
一个好的事件描述的是生产方领域里已经发生的事情。OrderAccepted 比 ProcessOrder 更强,因为它陈述一个事实、标明归属,并且把「这件事对我意味着什么」的解释权留给消费方。
好的事件契约包含:
- 稳定的标识;
- 带版本的 schema;
- 领域事实实际发生的时间;
- 足够的上下文,使消费方不必为每条消息回调生产方;
- 关于敏感数据与保留期的明确策略。
至少一次投递会改变应用的写法
大多数生产管道都应当假设存在重复。因此幂等不是中间件的一个开关,而是应用自身的行为。
消费方需要一个稳定的幂等键,以及「我处理过这条消息」与其业务副作用之间的原子关系。取决于存储,这可能是唯一约束、inbox 表、条件更新,或者一个天然幂等的状态迁移。
重试必须有界且可观测。死信队列本身不构成恢复策略——除非有人负责重放,并且能说清楚重放是否安全。
归属比拓扑更重要
生产方对事件的语义和质量负责;平台对传输可靠性和运维标准负责;每个消费方对自己的处理、积压和恢复负责。
当这些责任含糊不清时,团队就会用共享数据库、同步回调和手工修复脚本来打补丁。系统看起来是事件驱动的,行为上却是一个分布式单体。
宁可少而有意义的事件
把每一次数据库变更都发出去,只会制造噪音,并把消费方耦合到存储细节上。从其他能力真正需要的领域事实开始;当出现明确的消费方和被理解的契约时,再增加事件。
目标不是最大程度的异步化,而是「能各自独立演进,并且有恢复故事」。
相关文章
设计高吞吐系统,别跑偏
在选型之前,先把容量、延迟、正确性与运维风险拆开来看的一套实用框架。
系统设计演练:高吞吐规则引擎
在 45 分钟的系统设计面试里,如何组织需求、数据流、扩展性、正确性与运维。
在做类似的事情?
很乐意就分布式系统、交付流程和应用 AI 交换意见。