凌晨3点,那个过度设计的系统架构,终究还是崩了……

Vinod Pal 2026-04-02 09:44:43
我以前一直认为,图表中的方框越多,设计就越好。但多年从事大型企业系统开发工作后,我才明白事实恰恰相反。

 

大多数系统崩溃并非因为缺少工具,而是因为工具过多。

 

 

以下五种架构实践改变了我对系统设计的看法。

 

一、仅在必要时拆分系统

 

我们曾从一开始就采用微服务架构构建了一个支付系统,初衷是打造一个从上线第一天起就具备可扩展性的系统。

 

 

即使流量很低,每次支付请求也会触发多次网络调用。任何服务一旦出现故障,整个支付流程都会失败。

 

除此之外,调试也让人头疼,它需要翻阅大量日志以及协调各个团队。

 

此外,即便是简单的更改,也需要在相关服务中进行部署。

 

让我们来简化一下这个架构。

 

 

通过保持逻辑边界的同时消除物理隔离,我们大幅减少了潜在的故障模式。

 

现在部署更容易了,调试速度也更快了。

 

当需要扩展时,我们可以将使用频率最高的服务之一拆分出来,使其成为独立的微服务。

 

旨在包罗万象的架构,通常什么都处理不好。

 

二、避免过度抽象

 

我们接手了一个比较难维护的订单管理系统,第一反应是通过添加抽象层来对其进行整理。

 

为了“标准化”行为,我们引入了泛化服务、共享仓库以及各种基类。

 

结果却比之前更糟。

 

 

理解订单流程需要在各个接口和基类之间来回切换。业务规则分散在各个层级,即使是简单的修改,成本也很高。

 

抽象消除了重复,但也抹去了含义。

 

于是我们改变了策略。

 

 

我们没有采用通用的抽象层,而是明确定义了工作流程。订单创建、定价和履约都体现在具体的代码中。

 

虽然存在少量代码重复,但这都是有意为之且清晰可见的。这样一来,变更的影响范围得以本地化,故障的追踪也变得更加容易。

 

简单的系统,出了故障会一目了然;复杂的系统,一旦故障则难以捉摸。

 

三、 架构设计应以简洁为主,而非花哨

 

在一个结账系统中,我们曾对整个流程采用了事件驱动架构,每一步骤都负责发布和消费事件。

 

这套设计在白板上看起来优雅无比,在生产环境中却令人痛苦不堪。

 

 

先等一下,你觉得这种架构存在什么明显的缺陷?

 

大多数讨论都围绕事件排序、重试和消费者延迟展开。没有哪个服务明确负责订单的最终结果。一旦发生故障,订单就会处于部分处理状态,需要人工干预。

 

这个架构以牺牲清晰度为代价,换取了所谓的灵活性。

 

我们用一套简洁的同步结账服务,取代了原先完全事件驱动的流程。

 

 

整个结账流程由一个服务负责:它验证购物车、处理支付,并最终返回明确的成功或失败结果。

 

事件机制虽仍被采用,但仅用于分析和通知等辅助功能。核心业务流程依然保持线性,易于理解。

 

现在,任何故障都能即刻显现。订单要么完成,要么明确失败,绝不会处于模棱两可的状态。

 

当一种架构需要冗长的讲解才能说明其工作原理时,那么它可能设计得太复杂了。

 

四、你不需要它 (YAGNI)

 

这个产品的适用范围很窄。

 

用户提交反馈意见,管理员进行审核。

 

但实际的架构远比这复杂得多。

 

 

理论上,这套设计是为未来扩展做准备。但实际上,它优化的却是一个永远不会到来的问题,这也造成了诸多复杂性:

 

  • 单个服务中的多个架构层

  • 基于事件驱动的反馈提交流程

  • 反馈、状态和审计日志分别用单独的表格记录

  • 功能标志用于保护未完成或未使用的功能

 

这些复杂性都集中在一个服务中,它并没有解决任何实际问题,仅仅是对未来的一种臆测。

 

简化后的架构大致如下:

 

 

通过移除那些无用的抽象层、数据表与基础设施,系统变得不言自明。

 

大多数系统都会因为应对从未出现的问题而做出的决策不堪重负,最终崩溃。

 

五、配置过多并非总是好事

 

某个内部系统过度追求灵活性,几乎所有行为都由配置驱动。

 

功能标志、环境变量和多个配置文件都影响着核心逻辑。绝大多数生产事故并非由代码缺陷导致,而是源于错误的配置。

 

 

理论上,这看起来很灵活,但实际上却有很多隐藏的复杂性:

 

  • 运行时加载多个配置源

  • 控制关键执行路径的功能标志

  • 环境特定行为遍布整个代码库

 

要了解系统的运行方式,必须先了解它的部署方式。

 

现在,让我们来看一下简化后的架构:

 

 

  • 清除代码中直接定义的默认值

  • 功能标志仅用于临时发布

  • 配置仅限于实际环境差异

 

减少活动部件之后,部署变得更加安全,系统行为变得可预测,代码本身也变得易于理解。

 

当灵活性成为首要目标时,清晰度通常是第一个被牺牲的。

 

简洁的架构并不意味着设计薄弱。它意味着剔除不必要的复杂性,使系统在持续演进中依然易于理解。

 

稳固的系统始于简洁,它们的复杂性,是在时间的沉淀中逐步积累而来的。

 

作者丨Vinod Pal      编译丨dbaplus社群
来源丨网址:https://medium.com/javarevisited/how-simpler-architectures-made-me-a-better-senior-developer-8873a44e0a4c
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
最新评论
访客 2024年04月08日

如果字段的最大可能长度超过255字节,那么长度值可能…

访客 2024年03月04日

只能说作者太用心了,优秀

访客 2024年02月23日

感谢详解

访客 2024年02月20日

一般干个7-8年(即30岁左右),能做到年入40w-50w;有…

访客 2023年08月20日

230721

活动预告