80.3 架构设计文档模板

一句话

架构文档不是 “写作文”,而是按评审会要问的顺序把问题答完:一份回答 “为什么是它”(选型),一份回答 “具体怎么做”(设计);两份分开写,评审才能在 1 小时内给出结论,而不是听完 1 小时汇报后说 “再想想”。

两份文档,两拨读者

文档 要回答的问题 读者 合理长度
备选方案(选型文档) 为什么是它?为什么不选另外两个? 决策者:技术委员会、业务负责人 5–15 页
架构设计(设计文档) 具体怎么做、怎么落地、怎么回滚? 执行者:开发、运维、DBA、测试 20–50 页

把两份合成一份,必然出现 “决策者嫌啰嗦、执行者嫌没细节”;拆开写的成本只是多一次目录,收益是两边都读得下去。

备选方案:五章

章 写什么 最常见的缺陷
① 需求介绍 背景、目标、范围(明确不做什么) 只写目标,不写边界,评审时才发现对 “做什么” 理解不同
② 需求分析 5W1H + 8C,NFR 全部落到数字 只有功能描述,没有 P99 / 吞吐 / 可用性
③ 复杂度分析 高可用、高性能、可扩展各一句 “本方案的主要矛盾是 X” 三条都写 “非常重要”,等于没说
④ 备选方案 至少 3 个,每个都有架构图 + 关键设计点 只写自己想推的那一个
⑤ 方案评估 360 度环评:对 8C 逐项写 “满足 / 不满足 / 代价” 用 “更好、更快” 代替逐项对比

5W1H 与 8C:把 “需求” 变成可评估的维度

维度 问什么
Who 谁用?内部用户、外部 C 端、还是系统间调用
When 什么时候用?峰值在何时、持续多久
What 做什么?核心用例 3–5 个
Where 在哪跑?单机房 / 多地域 / 边缘
Why 为什么现在做?不做会怎样
How 关键业务流程(一张时序图)

8C 是评估备选方案的打分维度,每一项都要能写 “满足 / 不满足 / 代价是什么”:

维度 典型问题
性能 P99、峰值吞吐、容量上限
成本 三年 TCO(机器 + 人力 + 迁移)
时间 多久能上线?会不会影响已有排期
可靠性 可用性几个 9、RPO/RTO
安全性 认证授权、数据分级、攻击面
合规性 等保、数据出境、审计留痕
技术性 团队会不会、社区活不活跃、能否招到人
兼容性 与现有系统、协议、数据格式的兼容成本

⚠️ 最容易漏的是 成本 和 合规性:评审现场被问 “三年多少钱” 或 “数据能不能出境” 时答不上来,方案会当场被打回。

架构设计:六章

章 写什么 验收标准
① 总体方案 一段话说清整体思路 + 一张总图 不看后文也能知道这套系统长什么样
② 架构总览 架构图 + 每个模块一句职责 + 关键设计点(3–5 条) 图上每个方块在正文都有对应描述
③ 核心流程 3–5 条主链路的时序图(下单、支付、回调…) 含成功、失败、重试三条路径
④ 详细设计 高可用 / 高性能 / 可扩展 / 安全 / 其他 每节都要有措施 + 数字 + 失效时的表现
⑤ 部署方案 资源清单(几台、什么规格)、网络拓扑、容量水位 能照着买机器、开网络策略
⑥ 演进规划 下一版加什么、什么条件下触发重构 写触发条件,不写 “未来会优化”

🔑 “不涉及”必须写 “无”,不许空着:空着会被评审默认成 “遗漏”;写 “无” 才表示 “评估过了,确实不需要”。这条能砍掉一半的来回。

容量估算:一节算出可评审的数字

设计文档里最容易被跳过、又最影响结论的一段。三段式:均摊 → 峰值 → 余量。

# 从业务量推到 TPS/QPS,三段都要写进文档
WRITE_PER_DAY = 10_000_000      # 每天新增 1000 万条
SUBSYSTEMS    = 10              # 一条数据被 10 个子系统读取
PEAK_FACTOR   = 3               # 峰值是均值的 3 倍
HEADROOM      = 4               # 再留 4 倍余量

sec = 86400
w_avg = WRITE_PER_DAY / sec
r_avg = WRITE_PER_DAY * SUBSYSTEMS / sec
print(f"均值: 写 {w_avg:.0f}/s, 读 {r_avg:.0f}/s")
print(f"峰值 x{PEAK_FACTOR}: 写 {w_avg*PEAK_FACTOR:.0f}/s, 读 {r_avg*PEAK_FACTOR:.0f}/s")
print(f"余量 x{HEADROOM}: TPS {w_avg*PEAK_FACTOR*HEADROOM:.0f}, QPS {r_avg*PEAK_FACTOR*HEADROOM:.0f}")

本机实测输出(Python 3.14 / macOS arm64):

均值: 写 116/s, 读 1157/s
峰值 x3: 写 347/s, 读 3472/s
余量 x4: TPS 1389, QPS 13889

文档里就该写:“按 1389 TPS / 13889 QPS 做容量规划,其中读 QPS 由 10 个子系统分摊”。三段的每一段都要暴露给评审——只给最终数字,评审无法判断你到底有没有考虑峰值。

同类需要写进文档的阈值示例:

项 参考值
主备复制延迟告警线 超过 30 秒 告警(超过即读流量可能读到过期数据)
ZooKeeper 临时节点超时 默认 10 秒(决定故障摘除的检测延迟,见 48.2 服务发现)
跨城同步写延迟 ≈30ms 物理下限(决定 RPO=0 能不能做,见 36.4 两地三中心与多活)

十条写作硬规则

# 规则 为什么
1 每个 NFR 后面跟数字 “高可用” 无法验收,“4 个 9” 才能
2 每个 “没选” 的方案写一句否决理由 + 一个数据 否则评审会重新讨论一遍
3 图上每个方块,正文有一句职责 图与文字不一致是文档最常见的死法
4 正文写结论,理由进 ADR(58.1 ADR 实践) 文档可读,决策可追溯
5 不涉及就写 “无” 空着会被当成遗漏
6 部署方案要能直接下单(规格 × 台数 × 网络) 否则上线当天才发现没资源
7 演进规划写 “触发条件” 而不是 “未来优化” “未来” 永远不会来
8 带版本与变更记录(谁、为什么改) 半年后没人记得为什么这么设计
9 术语统一,指向术语表 同一个东西三个名字,评审必吵
10 未决问题单列一节,放在最前面 评审会先解决争议,再听方案

生产落地:指名 → 可抄 → 可验 → 可退

指名:文档用 Markdown 存 Git(可 diff、可评论、可回滚),图用 Mermaid(GitHub/GitLab 原生渲染)或 PlantUML;画图的模型与规范见 80.1 C4 模型 与 80.2 架构图规范。评审流程见 58.3 架构评审。

可抄(目录骨架,直接建文件):

docs/design/<系统名>/
├── 00-选型.md          # 需求介绍 / 需求分析(5W1H+8C) / 复杂度 / 备选(≥3) / 评估
├── 01-设计.md          # 总体方案 / 架构总览 / 核心流程 / 详细设计 / 部署 / 演进
├── 02-容量.md          # 均摊 → 峰值 → 余量,附计算脚本
├── 03-风险.md          # 未决问题、已接受的风险与理由
└── adr/                # 每个关键决策一篇(格式见 ADR 实践)

文档的章节顺序不是拍出来的,它对应见 58.6 架构设计流程与三原则 里的四步流程(识别复杂度 → 3 个备选 → 环评 → 详细设计)。

可验:拿 58.3 架构评审 的十条清单逐条对,缺一条就打回。三个最硬的检查点:

检查 不合格的样子
备选方案 ≥ 3 个且各有一张图 只有一个方案,评审退化成 “要不要做”
NFR 全是数字 出现 “性能好、可用性高”
部署方案能直接下单 只有 “部署在 K8s” 一句话

可退:小改动(加一个接口、换一个依赖)不套这套模板,用一页纸 RFC:背景 / 方案 / 影响面 / 回滚方式。模板是给 “不可逆、跨团队、要花钱” 的决策用的,滥用会让人把写文档当负担。

反模式

反模式 后果
先有方案,再补需求分析 评审第一个问题就崩:“你的约束是什么?”
备选方案只写一个 评的不是 “选哪个”,而是 “要不要做”,决策质量下降
用形容词代替数字 “高可用、低延迟” 无法验收,也无法比较
8C 只写技术维度 漏掉成本与合规,方案在最后一关被打回
设计文档没有部署方案 上线前才发现资源、网络策略、证书都没准备
图改了正文没改 半年后没人知道哪份是准的
文档只存邮件/IM 找不到最新版,新人只能问人
一份文档既做选型又做设计 决策者被细节淹没,执行者看不到细节

自检

Q1 为什么选型文档和设计文档要分开写?

▸ 答案:因为读者与要回答的问题不同。选型文档面向决策者,只需回答 “为什么是它、为什么不选别的”,5–15 页就够;设计文档面向执行者,要回答 “怎么做、怎么部署、怎么回滚”,需要 20–50 页的细节。合成一份的结果是决策者嫌长、执行者嫌浅,两边都不满意。

Q2 备选方案为什么至少写 3 个?

▸ 答案:1 个方案时评审只能决定 “做不做”,没有比较就没有取舍;2 个方案常常是 “一好一坏” 的陪衬;3 个才能逼出真正的权衡(通常是一个偏保守、一个偏激进、一个折中)。这也是 58.3 架构评审 清单第 2 条的来源。

Q3 8C 里最容易被漏掉的两个维度是什么?漏了会怎样?

▸ 答案:成本与合规性。成本漏了,方案可能在预算评审时被推翻(三年 TCO 是机器 + 人力 + 迁移,不只是机器);合规漏了,可能在数据出境、等保、审计环节被卡死,返工成本远高于重新设计。

Q4 为什么 “不涉及” 必须写 “无”,不能空着?

▸ 答案:空着在评审眼里等于 “没想”。写 “无” 表示评估过并确认不需要,是结论;空着是未完成的格子。这一条能显著减少 “这里是不是漏了” 的来回确认。

Q5 容量估算的三段是什么?只写最终数字有什么问题?

▸ 答案:均摊 → 峰值 → 余量。只写最终数字(比如 “1389 TPS”),评审无法判断你有没有考虑峰值倍数与冗余系数,也无法在不同方案之间比较;三段都写出来,别人才能替换假设(峰值从 3 倍改 5 倍)自己重算。

Q6 设计文档里 “关键设计点” 和 “详细设计” 有什么区别?

▸ 答案:“关键设计点” 是3–5 条决定这套架构形状的选择(例如 “按用户分片、跨分片异步对账”),放在架构总览里,让读者一眼看到 “这套方案的骨架”;“详细设计” 是每个子系统怎么实现(表结构、接口、超时、重试),放在后面。混在一起,读者会迷失在细节里看不到骨架。

Q7 为什么文档要进 Git,而不是放在 Confluence?

▸ 答案:因为文档会过期,而过期的根因是 “更新成本高 + 与代码分离”。放进 Git 后,改代码的同一个 PR 里改文档,评审代码时顺手评审文档;还能 diff(看到改了哪一行)、能回滚、能按版本追溯。Confluence 的问题不是工具差,而是 “图与代码分属两个事实源”。

关联