知识卡片

分布式单体架构风险:教条式事件驱动的真实案例

普通读书笔记卡

内容

系统设计成事件驱动往往是为了减少耦合,但教条式滥用反而可能意外增加耦合,制造出”分布式单体架构”——一个本该被当作整体维护的代码库,却以分布式的方式分开保存和部署,改一处就要连带重新部署好几处。书中给出的真实案例:一个文档管理系统项目里,页面微服务只需发布”页面已创建”事件,授权服务监听后自动创建对应的授权条目,看似解耦得很好;但授权服务实际上必须理解”页面已创建”“文档已关联”等等来自其他上下文的具体事件语义——结果是每当系统其他部分有改动,授权服务往往也不得不跟着重新部署,因为它需要认得新出现的事件类型,这就是典型的分布式单体:微服务边界上物理分开了,但语义和变更耦合在一起,代码库实质上还是一个整体。团队后来的重构方案是给授权服务加一个清晰的API,其他微服务如果需要变更授权状态,都必须主动调用这个API,而不是让授权服务反过来去理解各种事件——这样授权服务变得非常稳定:谁该在什么事件下采取什么行动的决策,被转移到了真正拥有对应领域知识的微服务(比如关心页面的那个服务)里去做,而不是塞进一个本不该懂这些领域细节的下游订阅者。这个案例警示:不能因为整体架构是”事件驱动”,就默认所有跨服务通信都该走事件——是否解耦、耦合发生在哪里,取决于具体设计,而不是通信风格本身的标签。

参考来源

- 位置:《流程自动化实战:系统架构和软件开发视角》第8章《平衡编排与编制》"8.1.3 分布式单体架构的风险"(源文件:_epub-src/EPUB/xhtml/Section0001_0012.xhtml) - 结论依据:原文用页面/授权服务的真实项目案例说明授权服务被迫理解多个上下文事件、随其他部分变更被迫重新部署的分布式单体问题,并说明重构后授权服务提供API、由拥有领域知识的服务主动调用带来的稳定性改进,直接支撑本卡片结论。 - 原始内容:虽然这样看起来解耦得很好,但授权服务必须知道"页面已创建""文档已关联"等事件……这就是所谓的分布式单体架构……哪个事件要采取哪些行动的决策被转移到了具有领域知识的微服务中。