大多数系统不是一夜之间变复杂的。
真正的变化,往往发生在某一次非常“正确”的优化之后。
那次优化有充分理由、有数据支撑、甚至还救过一次线上问题。
但几年后回头看,它却成了整个系统复杂度的起点。
一、所有复杂系统,最初都很“干净”
几乎每个系统都有一个阶段:
- 一个服务
- 一套数据库
- 一次发布
- 出问题能快速回滚
这个阶段大家都很舒服,也很自信。
直到某一天,系统开始出现一句熟得不能再熟的话:
“这里其实可以再优化一下。”
二、第一次“看似合理”的优化,通常长这样
1️⃣ 为了性能,加了一层缓存
动机非常正当:
- 接口慢
- 数据变化不频繁
- Redis 很成熟
于是缓存加上了,QPS 上来了,大家都很开心。
但后续慢慢出现:
- 数据不一致
- 缓存更新逻辑分散在各处
- 排查问题要同时看 DB、缓存、消息
这一步不是错,但它是复杂度的第一个拐点。
2️⃣ 为了解耦,引入异步和消息
动机也很合理:
- 接口响应慢
- 不该同步做那么多事
- MQ 能削峰填谷
于是同步调用变成异步投递。
后来的世界变成了:
- 调用链断裂
- 失败重试语义不清
- “到底谁该负责一致性”说不清楚
系统开始不再是一个时序可控的整体。
3️⃣ 为了复用,开始抽公共组件
这个阶段通常会出现:
- 通用 SDK
- 公共中间层
- 所有服务都要依赖它
一开始是“统一”,后来变成:
- 谁都不敢改
- 改一次影响全局
- 升级成本指数级上升
系统并没有更简单,只是复杂度被集中起来了。
三、真正的问题:优化本身没错,错的是“没算后果”
这些优化都有一个共同点:
它们只解决了“当前问题”,却引入了“长期复杂度”。
而当时通常忽略了三件事:
① 心智成本
- 新人要多久才能理解?
- 出问题要看几层组件?
② 回滚成本
- 能不能一键撤回?
- 数据是否可逆?
③ 演进成本
- 未来改动是不是更难?
- 是否被设计“锁死”?
四、系统失控,往往不是因为一次大改
而是因为很多次**“小而正确”的决定叠加**:
- 一个缓存
- 一个异步
- 一个中间层
- 一个优化参数
单独看都没问题,放在一起就变成:
系统谁都不敢动,但谁都在骂。
五、后来我才意识到的一些判断原则
这些不是原则,是后来吃过亏总结出来的直觉。
✅ 优化前,我会先问:
如果三个月后发现这是个坑,能不能退回去?
✅ 架构设计时,我更关心:
这个设计,是在降低问题数量,还是在转移问题位置?
✅ 当有人说“先这样,后面再优化”:
我会默认:后面大概率不会再动了。
六、真正成熟的架构,不是“高级”,而是“克制”
现在我对“架构优化”的态度变成了:
- 能不用缓存,就不用
- 能同步,就不异步
- 能简单,就不抽象
不是因为技术不行,而是因为:
系统复杂度一旦上去,很少有机会再降下来。
结语
系统不是被“错误设计”搞复杂的,
而是被一次次看似合理、局部正确的优化推着往前走。
所以现在再听到那句:
“这个地方其实可以再优化一下”
我通常会先停下来想一件事:
这次优化,是在解决问题,
还是在为未来制造一个更难的问题?