Skip to content

02 · 架构师的思考框架

上一章说「架构是在取舍中做重要决策」。这一章给你一套可以照着走的章法,把「拍脑袋」变成「有迹可循」。任何系统,都能用这一套流程拆开。


好消息:做架构判断是有章法的

很多人以为,架构判断是种玄学——靠天赋,靠十年踩坑攒出来的「感觉」。这话对了一半:经验确实重要。但另一半是,顶尖架构师脑子里其实跑着一套相当固定的流程,只是熟练到自己都没意识到。

我们要做的,就是把这套流程拆出来,让你能有意识地、一步步地走。等你走熟了,它也会沉淀成你的「感觉」——但那是建立在章法之上的感觉,而不是凭空的直觉。

这套流程长这样:

   ┌─────────┐    ┌─────────┐    ┌──────────┐    ┌──────────┐    ┌────────┐    ┌────────┐
   │  需求   │──▶ │  约束   │──▶ │ 质量属性  │──▶ │ 候选方案  │──▶ │  取舍  │──▶ │  决策  │
   └─────────┘    └─────────┘    └──────────┘    └──────────┘    └────────┘    └────────┘
   系统要做       有哪些不能      系统要「做       有哪几种         每个方案      选一个,
   什么?         逾越的边界?    得多好」?       搭法?           各拿什么       并写下
                                                                 换什么?      为什么
        │                                                                          │
        └──────────────── 业务/规模变化时,回到起点重走一遍 ◀──────────────────────┘

注意最下面那条返回的箭头:这不是一次性走完就结束的流程,而是一个会反复重走的循环。 业务变了、规模涨了,约束和质量目标就变了,当初的最优解可能就不再最优——架构因此需要演进(这是第 08 章的主题)。

下面我们逐段拆开。重点会放在第二、三段(约束和质量属性),因为那是新人最容易跳过、却最能拉开差距的地方。


第一步:需求 —— 但要分清两种需求

一切从需求开始。但**「需求」这个词,藏着架构里最重要的一道分界线**,大多数新人从没注意过:

功能性需求:系统要「做什么」。非功能性需求(质量属性):系统要「做得多好」。

这道分界线,值得你刻在脑子里。我们用一个例子把它讲透。

假设需求是:「做一个能上传图片、并分享给别人看的服务」。

功能性需求(做什么)很容易列:

  • 用户能上传图片
  • 用户能拿到一个链接
  • 别人能通过链接看到图片
  • 用户能删除自己的图片

这些是「系统得有这些功能」。但请注意:仅凭这些,你根本没法做架构判断。 因为——

「能上传图片」,是给 100 个人用,还是给 10 亿人用? 「别人能看到」,是要求点开秒出,还是转圈三秒也行? 「能分享」,图片要存一辈子,还是七天后自动删? 某个机房着火了,这些图片是可以丢,还是一张都不能少?

这些问题的答案,才真正决定了系统该长什么样。 而它们,全都是质量属性(做得多好):

  • 性能:点开图片要在 200 毫秒内显示。
  • 可扩展性:要能从 100 用户平滑长到 10 亿用户。
  • 可用性:全年宕机不超过几分钟。
  • 持久性:图片一旦上传,丢失的概率要极低(比如「十一个九」)。
  • 成本:存十亿张图,不能贵到把公司拖垮。

这是架构师最重要的基本功:看到「做什么」,立刻去追问「做得多好」。

功能性需求决定了系统「能不能用」;质量属性决定了系统「该怎么搭」。 同样是「上传图片」,要求秒开 + 永不丢失 + 十亿规模,和要求「能用就行 + 个人小工具」,会导出两套完全不同的架构。

一句话:功能性需求是地基的「用途」,质量属性才是地基的「规格」。 只看用途不看规格,你盖不出对的楼。

为什么新人总跳过质量属性?因为功能性需求是「显性的」——产品经理会写在文档里,白纸黑字。而质量属性是「隐性的」——很少有人主动告诉你「这个要支撑十亿用户、绝不能丢数据」,你得自己去问出来。 这正是下一节「问对问题」要解决的事。


第二步:约束 —— 你不是在真空里做设计

新人常以为,架构是在追求「理论上最好的方案」。但现实是:你永远是在一堆「不能逾越的边界」里做设计。 这些边界,就是约束。

约束和质量属性的区别在于:质量属性是「你想达到的目标」(越好越好),约束是「你绕不开的限制」(就这条件)。 一个是你追求的,一个是给你框死的。

常见的约束有这么几类:

约束它会怎么逼你
团队规模三个人的团队硬上几十个微服务?光运维就把人累垮。架构复杂度不能超过团队的驾驭能力。
时间「下周必须上线」和「我们有一年」,会逼出完全不同的方案。时间紧,就得选「现在能交付」的,而不是「理论最优」的。
预算钱决定你能用多少机器、多贵的服务、养多少人。再优雅的方案,烧不起就是空谈。
合规 / 法规「数据必须存在境内」「医疗数据要满足某某标准」——这类约束是红线,不是「尽量」,是「必须」,违反了方案直接作废。
已有系统大多数时候你不是从零开始,而是要和一堆「祖传系统」共存。你的设计得迁就它们的接口、它们的脾气。
第三方依赖你依赖的支付网关、云服务、外部 API,它们的能力上限和故障,就是你的约束。

关键认知:约束不是来添堵的,约束是来帮你「砍掉选项」的。

一个没有约束的设计题(「设计一个完美的系统」)其实无从下手,因为选项无穷多。一旦你知道「三个人、三个月、必须合规、要对接老系统」,绝大多数花哨方案当场出局,真正可行的方案就那么几个。 约束越清晰,决策越容易。

所以,新接到一个任务时,先别想方案,先把约束摸清楚。 摸清约束的人,往往比急着画方案的人,最后做得又快又稳。


第三步:质量属性 —— 列一份你的「考量清单」

第一步我们已经明白质量属性有多重要。这一步,给你一份常见质量属性清单,作为你每次思考时的「检查表」——不是每一项都重要,而是逐项过一遍,确保没漏掉那个会要命的

质量属性一句话解释
性能(Performance)系统反应有多快。包括延迟(单次操作多久)和吞吐(单位时间能处理多少)。
可用性(Availability)系统有多大比例的时间是「活着、能用」的。常用「几个九」衡量。
可靠性 / 持久性(Reliability / Durability)数据会不会丢、操作会不会出错。「持久性」特指存进去的数据不会莫名消失。
可扩展性(Scalability)用户/数据涨上来时,系统能不能靠「加机器」从容应对,而不是推倒重来。
一致性(Consistency)多个地方看到的数据是否一致。涉及「刚写的能不能立刻读到」「不同用户看到的是否同一份」。
安全性(Security)能不能挡住攻击、防住越权、保护好敏感数据。
成本(Cost)建设和运营要花多少钱。架构师常常忘了它也是一种「质量」。
可维护性(Maintainability)系统好不好改、好不好懂。新人多久能上手,加个功能要动多少地方。
可观测性(Observability)出了问题,你能不能快速看出「哪里坏了、为什么坏」。
可演进性(Evolvability)业务变化时,架构能不能跟着长大,而不是被锁死。

用法很简单:拿到一个系统,把这张表从头到尾过一遍,对每一项问「它对我这个系统重要吗?目标是多少?」

比如做一个「内部报表工具」:性能?中等就行。可用性?挂半小时也能忍。一致性?数据准就行,不要求实时。成本?能省则省。——你会发现大部分项要求都不高,这本身就是重要信息:它告诉你「别过度设计」。

再比如做一个「支付系统」:一致性?钱不能算错,最高优先级。 可靠性?一笔都不能丢。 安全性?红线。 ——同一张表,导出的却是完全不同的侧重。

这份清单,正是每个架构模板里**「质量属性表」**的来源。等会儿你去看 AI 对话产品模板 的第 3 节,会看到它列出了「首字延迟、吞吐、成本、可用性、安全」——那就是把这张通用清单,套到「AI 对话」这个具体场景上的结果。通用框架 + 具体场景 = 那张表。


贯穿始终的核心观点:没有银弹,只有取舍

现在到了整套框架的灵魂。如果这一章你只能记住一句话,记住这句:

没有银弹,只有取舍。任何架构决策,本质都是「用 A 换 B」。

「银弹」是个老说法,意思是「能一击解决所有问题的万能方案」。在架构里,银弹不存在。 每一个让你在某方面变好的选择,几乎都会让你在另一方面变差。

  • 想要更快?常常要牺牲成本(加缓存、加机器)或一致性(读到的可能是旧数据)。
  • 想要强一致?常常要牺牲性能可用性(得等所有节点同步好)。
  • 想要高可扩展?常常要牺牲简单性(系统变复杂,运维变难)。
  • 想要快速上线?常常要牺牲可维护性(欠下技术债,以后还)。
        想往这个方向加强 ───▶  往往要从那个方向割肉
        ─────────────────────────────────────────
        性能 ▲                  成本 ▼ / 一致性 ▼
        一致性 ▲                性能 ▼ / 可用性 ▼
        可扩展性 ▲              简单性 ▼ / 成本 ▼
        安全性 ▲                便利性 ▼ / 性能 ▼
        上线速度 ▲              可维护性 ▼(技术债)

这不是说做架构很悲观,恰恰相反:当你接受「凡事皆有代价」,你就从「找最好的方案」(找不到)转向了「找最合适的取舍」(找得到)。 后者才是真正的架构工作。

由此引出一条极其有用的判断标准:

如果有人给你一个方案,说它「哪儿都好,没有任何缺点」——那不是因为方案完美,而是因为他没想清楚。

一个想清楚了的人,一定能告诉你「这个方案好在哪、同时牺牲了什么、为什么这个牺牲值得」。看得到取舍,是想清楚了的标志;看不到取舍,是没想清楚的标志。 你评估别人的方案、或者审视自己的方案时,这一条几乎是万能的试金石。


怎么走完这套框架?关键是「问对问题」

框架是骨架,真正让它转起来的,是提问。前面说过,质量属性和约束大多是「隐性的」,得靠你问出来。所以,会问问题,是架构师的核心手艺。

下面这几个问题,几乎适用于任何系统。拿到一个新需求,先把它们问一遍:

┌────────────────────────────────────────────────────────────┐
│  架构师的「灵魂六问」                                          │
├────────────────────────────────────────────────────────────┤
│  1. 规模多大?    现在多少用户/数据?峰值多少?              │
│  2. 读写比?      是读多写少,还是写多读少?                 │
│  3. 一致性要求?  刚写的必须立刻能读到吗?能容忍短暂不一致吗? │
│  4. 增长预期?    一年后会涨到多少?是平缓还是会爆发?       │
│  5. 失败的代价?  这个东西挂了/数据丢了,后果有多严重?      │
│  6. 有什么约束?  团队多大?多少时间?多少预算?有无合规?   │
└────────────────────────────────────────────────────────────┘

为什么是这六个?因为它们每一个,都直接锚定一类架构决策:

  • 规模增长,决定你要不要、何时要为「扩展」做准备。
  • 读写比,决定你的系统该往「读优化」还是「写优化」倾斜(这会深刻影响数据怎么存,见第 05 章)。
  • 一致性要求,决定了那个最经典、最折磨人的取舍:一致性 vs 性能/可用性。
  • 失败的代价,决定你要在可靠性、可用性上投入多少——「丢了无所谓」和「丢一条就出大事」是两个世界。

这六问背后,藏着一个新人很难内化、但极其重要的心法:没有「最好的架构」,只有「在这组答案下最合适的架构」。

同样是「聊天功能」,做一个三个人用的内部工具,和做一个十亿人用的微信,答案天差地别——不是因为后者的工程师更厉害,而是因为两者的六问答案完全不同。所以,别一上来就找「正确答案」,先把你的六问答清楚;答案变了,最优解就变了。


走一遍完整流程:设计一个「短链接服务」

讲了这么多,我们拿一个经典又小巧的例子,完整走一遍框架。注意我们的目标不是给出「标准答案」,而是演示「怎么想」。

需求:「做一个短链接服务,把长网址变成 short.ly/x7Kp9 这样的短链,点击后跳转到原网址。」(就是各种「短网址生成器」)

① 需求:先分功能 vs 质量

功能性需求(做什么):

  • 输入一个长 URL,生成一个短 URL
  • 访问短 URL,跳转到对应的长 URL
  • (可能)统计每个短链被点了多少次

就这么三条,简单到几乎没什么可设计的。真正的设计,藏在质量属性里。 于是我们开始问。

② 问对问题(灵魂六问)

  • 规模多大? 假设我们对标一个中等服务:每天新建 1000 万条短链。
  • 读写比? 关键洞察来了——短链是「生成一次,被点击无数次」的。 一条链接可能被分享后点几百万次。所以读(跳转)远远多于写(生成),读写比可能是 100:1 甚至 1000:1。
  • 一致性要求? 「刚生成的短链,要能立刻访问吗?」——最好能,但晚个一两秒也能忍(你刚生成完,通常不会真有人在那一瞬间就去点)。这是个重要的「松一点」的信号。
  • 增长预期? 链接只增不减,数据会无限累积。十年下来是个天文数字,得想好怎么存。
  • 失败的代价? 「跳转挂了」用户点不开链接,体验差但不致命;「数据丢了」——已经分享出去的短链全部失效,这是灾难,持久性要求高
  • 约束? 假设是个小团队、要尽快上线、预算有限。

③ 从答案里,质量属性自己浮现出来

把六问的答案翻译成质量目标:

质量属性目标来自哪个回答
读性能跳转要极快(< 50ms)读远多于写,跳转是核心体验
可扩展性(读)要扛住海量读请求读写比 100:1+,峰值在「读」
持久性短链绝不能丢失败代价:丢了等于已分享的链接全废
一致性可以「最终一致」晚一两秒能访问到,用户能忍
成本存储要省数据无限累积 + 预算有限

看到了吗? 三条朴素的功能需求,经过「问对问题」,长出了一张清晰的质量目标表。这张表,才是后面所有决策的依据。

④ 候选方案 & 取舍

现在带着这张表,我们看几个关键决策点,每一个都是一次取舍:

决策 A:短码怎么生成?

  • 方案一:对长 URL 做哈希,取前几位当短码。简单,但会撞车(不同 URL 哈希到同一个码),得额外处理冲突。
  • 方案二:用一个全局递增的计数器,把数字转成更短的字符表示。不会撞车,但需要一个「全局发号」的部件,这本身在高并发下是个挑战。
  • 取舍:方案一简单但要处理冲突;方案二干净但引入了「发号器」这个新的复杂点和潜在瓶颈。没有免费的午餐——选哪个,取决于你更怕「处理冲突的麻烦」还是「维护发号器的麻烦」。

决策 B:怎么扛住海量的「读」?

  • 我们的读写比是 100:1+,而且热门链接会被反复点
  • 这几乎是在向你喊:加缓存。 把热门短链的映射放进内存缓存,绝大多数跳转请求根本不用碰数据库。
  • 取舍:缓存让读变得飞快、还省了数据库压力(对上我们的「读性能」和「成本」目标),代价是多了一层要维护的东西,以及「缓存里是旧数据怎么办」的问题——好在我们前面问出了「能容忍最终一致」,所以这个代价我们承受得起。看,前面问对的问题,在这里直接帮我们拍了板。

决策 C:数据放哪、怎么存?

  • 数据形态极其简单:就是「短码 → 长 URL」的键值对应,而且几乎只按短码来查
  • 这种「简单键值、按 key 查、要海量、要快」的形态,天然适合键值型存储,而不是把它硬塞进复杂的关系型结构。
  • 取舍:这正是「数据的访问形态决定存储选择」这条通用原则的体现(下一章和第 05 章会反复出现)。

⑤ 决策 & 记下「为什么」

走到这里,你不只得到了一个方案,更重要的是——你能说清每个决策的理由和代价了:

「我们用缓存扛读,因为读写比悬殊且能容忍最终一致;代价是多一层维护和短暂的旧数据,但这个代价我们前面确认过能接受。我们用键值存储,因为数据形态是简单的按 key 查询。我们短码用 X 方案,因为……」

这,就是架构判断。 它和「我随便选了个数据库就开干」的区别,不在于用了什么技术,而在于每一步背后都有「为什么」和「代价」。把这些「为什么」记下来,就是第 08 章要讲的 ADR(架构决策记录)。


📌 真实案例:这套框架不是纸上谈兵

本章用「短链接服务」走了一遍六问。真实世界里的短链(BitlyTinyURL 等)正是这么设计的:读写比悬殊、重度缓存、KV 存储、唯一 ID 发号。

  • 想看这套框架产出的「成品」,直接对照本仓库 短链接服务模板——它的第 3 节(需求与约束)和第 8 节(关键决策)就是本章「六问 + 取舍」走到底的结果。

本章小结

  • 做架构判断有章法:需求 → 约束 → 质量属性 → 候选方案 → 取舍 → 决策,而且业务一变,就回到起点重走一遍。
  • 架构师最重要的基本功,是分清功能性需求(做什么)和质量属性(做得多好)。 功能决定「能不能用」,质量属性决定「该怎么搭」。前者显性、写在文档里;后者隐性、得自己问出来。
  • 约束不是来添堵的,是来帮你砍选项的。 团队、时间、预算、合规、已有系统、第三方依赖——摸清约束,可行方案就剩没几个了。
  • 没有银弹,只有取舍。任何决策都是用 A 换 B。 一个「哪儿都好、没有缺点」的方案,不是完美,是没想清楚。看得到取舍 = 想清楚了。
  • 会问问题是核心手艺。 灵魂六问:规模、读写比、一致性、增长、失败代价、约束。没有最好的架构,只有在这组答案下最合适的架构。
  • 短链接的例子告诉我们:三条朴素的功能需求,经过「问对问题」,能长出一张清晰的质量目标表,而那张表才是一切决策的依据。

这套框架,正好对应每个架构模板里的两个核心小节:「核心需求与约束」(对应本章的需求/约束/质量属性)和**「关键架构决策与权衡」**(对应本章的候选方案/取舍/决策)。

现在就去验证一下: 翻开 ../templates/ 里任意一个模板,直接看它的第 3 节和第 8 节,你会发现它们就是这套框架的实际产物。试着用本章的「灵魂六问」反推:它的设计者当初一定问过这些问题。

想清楚之后,你还得把它讲清楚——让团队里每个人都看懂你脑子里的系统。这就需要会画图。

👉 继续阅读:03 · 读懂与画好架构图