后端架构实战(一):好架构的本质——没有银弹,只有权衡

写在前面

这是「后端架构实战」系列的第一篇。我写了不少 .NET、分布式、中间件、数据库的笔记,讲的都是"零件"。这个系列想聊的是另一件事:怎么把零件搭成一辆车——也就是软件架构。

但开篇我不想聊微服务、不聊 DDD、不聊任何具体风格。我想先回答一个更根本的问题:到底什么是"好架构"?

答案只有两个字:权衡。理解了这一点,后面七篇才有意义。


一、架构到底是什么

很多人对架构的印象是"画框图"——几张分层图、几个箭头、一堆方框。那是架构的产出,不是架构本身。

1
2
3
4
5
6
7
8
9
架构的本质:在约束下,做"职责如何分配"的决策

  - 哪些东西放在一起,哪些东西拆开
  - 哪些决策现在做,哪些决策推迟
  - 哪些东西自研,哪些东西用别人的
  - 哪些质量属性优先,哪些先牺牲

  画图只是把这些决策记录下来。
  没有决策依据的图,就是 PPT。

一个判断标准:如果你说不出"我为什么这么选、放弃了什么",那你就没在做架构,只是在抄。


二、第一性原理:一切都是权衡

Fred Brooks 有句名言:"没有银弹"(No Silver Bullet)——没有任何一种技术或方法能让软件工程的本质难题一夜消失。架构同理:

1
2
3
4
5
6
7
8
不存在"最好的架构",只存在"在当前约束下最合适的架构"

  同一个系统,在不同团队、不同阶段、不同规模下,
  "好架构"的答案完全不同。

  10 人的电商团队和 1000 人的电商团队,
  "正确"的架构天差地别——
  不是谁对谁错,是约束变了。

所以资深架构师最常说的话不是"应该用 X",而是 “It depends”(看情况)。这不是圆滑,是因为架构决策永远依赖上下文


三、约束的四象限

“It depends” 到底 depend 什么?四个维度:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────────┐
│  1. 规模(Scale)                                         │
│     用户量、数据量、QPS、团队人数                          │
│     → 决定要不要拆、要不要分布式                          │
│                                                          │
│  2. 时间(Time)                                          │
│     上市压力、迭代节奏、技术债务容忍度                     │
│     → 决定先糙快还是先打好地基                            │
│                                                          │
│  3. 团队(Team)                                          │
│     人数、技能栈、分布式经验、运维能力                     │
│     → 决定能 hold 住多复杂的架构                          │
│                                                          │
│  4. 成本(Cost)                                          │
│     服务器、人力、第三方服务、维护开销                     │
│     → 决定自研还是采购、能上多少中间件                     │
└─────────────────────────────────────────────────────────┘

  四个维度互相牵制。规模涨了 → 团队要扩 → 成本要加 → 时间可能更紧。
  架构决策 = 在这四个约束的"可行域"里找最优解。

关键认知:约束是会变的。今天的最优解,半年后可能就是技术债。所以架构不是一次定死,而是要能演进(第七节会展开)。


四、几个经典的权衡

4.1 性能 vs 可维护性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
追求极致性能 → 紧凑的代码、手工优化、绕过抽象
  ✓ 跑得快
  ✗ 晦涩难懂、改一处崩三处、新人接手难

追求可维护性 → 清晰的抽象、分层、命名
  ✓ 好改、好懂、好测
  ✗ 多一层调用、多一点开销

  绝大多数业务系统:优先可维护性(性能够用就行)
  少数热路径(交易撮合、广告竞价):性能压倒一切

4.2 一致性 vs 可用性

这就是 CAP。分布式系统的所有痛苦都源于此:

1
2
3
4
5
要强一致 → 协调多数节点、锁、阻塞 → 牺牲可用性和性能
要高可用 → 允许暂时不一致 → 牺牲一致性,要处理冲突

  详见我写的《分布式系统学习笔记(一):CAP 与一致性》。
  本系列第五篇会讲它在数据层怎么落地。

4.3 简单 vs 灵活(最容易踩的坑)

1
2
3
4
5
6
7
8
9
过度设计(Over-engineering):
  为"将来可能要用"的需求,提前搭了一堆抽象层
  → 现在用不上,将来真要用时发现猜错了
  → 维护成本白白增加

  YAGNI 原则:You Aren't Gonna Need It。
  不要为想象中的需求买单。
  但也要留"可演进"的接缝——这不是矛盾,区别在于:
    抽象 ≠ 灵活;接缝 ≠ 提前实现。

4.4 自研 vs 采购

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
自研:完全可控、贴合业务、无授权费
  ✗ 要投入人力、要自己维护、要踩坑

采购/开源:成熟、快、社区支持
  ✗ 黑盒、受制于人、可能有授权/合规问题

  经验法则:
    核心竞争力、差异化能力 → 自研
    通用能力(消息队列、缓存、监控) → 用成熟方案
    不要重新发明轮子,除非轮子是你的核心业务。

五、两大反模式

5.1 不设计(Cargo Cult 抄作业)

1
2
3
4
5
6
"大厂都用微服务,我们也上微服务"
"别人用 K8s,我们也要 K8s"
→ 完全不看自己的规模、团队、问题

  这是把"别人的解"套到"自己的题"上。
  约束不同,照抄就是灾难。

5.2 过度设计(Resume Driven Development)

1
2
3
4
5
"我想在简历上写 K8s + Service Mesh + 事件驱动 + CQRS"
→ 一个日活 100 的内部系统,上了全套云原生

  简历好看了,系统难维护了,公司买单了。
  技术选型的依据应是"问题",不是"我想学/想用"。

这两种病的共同点:决策没有回到约束和问题上


六、架构是演进的,不是一次定死

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
架构的演进路径(也是本系列的主线):

  单体 ──→ 模块化单体 ──→ 按领域拆分 ──→ 微服务 ──→ 云原生

  每一步升级,都是在"旧架构扛不住新约束"时才发生:
    单体扛不住团队规模   → 模块化
    模块化扛不住并发     → 拆服务
    服务多了扛不住运维   → 云原生

  关键:
    不要跳级。跳级 = 把未来的税提前交,还可能白交。
    能用单体解决的问题,上微服务就是自找麻烦。

这也是为什么第二篇我要先为单体正名——大多数人低估了单体,高估了微服务。


七、怎么做一个架构决策

给一个可落地的决策框架:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
1. 把问题讲清楚
   不是"要不要上微服务",而是
   "当前的痛点是什么?是发布耦合、扩容困难,还是团队协作?"

2. 列出所有候选方案
   至少 3 个。哪怕第 3 个是"什么都不做"。
   只有一个方案不叫决策,叫拍脑袋。

3. 对照四象限约束评估每个方案
   规模 / 时间 / 团队 / 成本
   列出每个方案的收益和代价(尤其是代价)。

4. 选定,并记录为什么放弃其他方案
   这一步最重要。用 ADR(Architecture Decision Record)记下来:
     - 背景、决策、理由、后果
   半年后你会感谢自己。

5. 留好回滚 / 演进的接缝
   决策可能是错的,约束会变。
   确保架构能"进"也能"退"。

八、小结

  • 架构 = 在约束下分配职责的决策,画图只是产出
  • 没有银弹:不存在最好的架构,只有当前约束下最合适的
  • 约束四象限:规模、时间、团队、成本——架构决策永远依赖上下文
  • 四大经典权衡:性能↔可维护性、一致性↔可用性、简单↔灵活、自研↔采购
  • 两大反模式:不设计(照抄)、过度设计(简历驱动)
  • 架构是演进的:单体 → 模块化 → 拆服务 → 云原生,不要跳级
  • 决策要记录:用 ADR 写清"为什么这么选、放弃了什么"

下一篇,我先替"单体"说句公道话——模块化单体才是大多数团队被低估的最佳实践。