软件架构文档模板(免费)
架构文档通常是这样写出来的:一位新工程师入职,问系统是怎么拼在一起的,于是有人承诺"好好写下来"。他去搜软件架构文档模板,找到一份 2012 年的四十页 Word 文件或者一份大学的 PDF,填了一半,然后再也没打开过。一年后,下一位新人找到了它,信以为真,结果理解错了。
问题很少出在缺少模板上。问题在于模板什么都要,结果什么都完成不了;文档没有负责人,结果什么都不会更新。下面这份模板刻意做得很精简:一个 Markdown 文件,九个章节,每个章节之所以存在,是因为读它的人会用到。把它复制进你的代码仓库,无需注册,无需下载。然后再读一读逐章节的说明:每一部分该写什么,以及如何避免它过时。
架构文档是做什么用的(以及谁会读它)
架构文档回答的是代码无法快速回答的问题:系统是做什么的,它和什么通信,它是如何拆分的,为什么这样拆分,以及已知哪些地方是脆弱的。它不是某个功能的设计规格,也不是 API 参考文档。
它有五类读者,心里点名想着他们来写会很有帮助:
| 读者 | 需要从中获得什么 | 会读的章节 |
|---|---|---|
| 入职第一周的新工程师 | 东西都在哪里,一个请求如何流转 | 上下文、容器、关键流程、术语表 |
| 设计变更的评审者 | 变更会影响什么,哪些已经决定了 | 容器、决策、质量目标 |
| 凌晨 3 点的值班工程师 | 什么依赖什么,已知什么容易出问题 | 容器、关键流程、风险 |
| 审计人员或安全评审 | 边界、数据流、外部相关方 | 上下文、约束、决策 |
| 一年后的你 | 当初为什么这样做 | 决策、风险 |
如果文档中的某个章节对他们都没有用,就删掉它。这条规则对文档质量的提升,胜过任何模板。
关于名称:「架构文档」、「系统设计文档」(SDD)和「软件架构文档」(SAD)大致指的是同一类东西。SDD 模板往往按项目或按功能编写,包含详细设计;架构文档描述的是系统当前的样子,并随系统一起变化。这里的模板属于后者。
模板(一个 Markdown 代码块)
把它复制到 docs/architecture.md(或根目录下的 ARCHITECTURE.md)并填写。所有尖括号里的内容都是占位符。不适用的章节请直接删除,不要留空。
# <系统名称>:架构
| | |
|---|---|
| 负责人 | <负责让本文档保持准确的团队或个人> |
| 上次评审 | <YYYY-MM-DD> |
| 下次评审 | <YYYY-MM-DD,或"每次修改第 3–5 节时"> |
| 状态 | <草稿 / 当前有效 / 正在被 X 取代> |
## 1. 上下文与范围
<两三句话:系统做什么、为谁服务、为什么存在。>
**用户**
- <角色>:<他们用系统做什么>
**外部系统**
- <系统>:<我们发送或接收什么,使用什么协议>
**不在范围内**
- <大家以为这个系统会做、但其实不做的事>
**系统上下文图(C4 第 1 层)**
<链接或嵌入。系统画成一个方框,加上每一类用户和每一个外部系统。>
## 2. 质量目标
当彼此冲突时优先保证的三到五项质量属性,按优先级排序。
| 优先级 | 质量属性 | 具体场景 |
|---|---|---|
| 1 | <例如:可用性> | <例如:推荐服务宕机时,结账仍能正常工作> |
| 2 | <例如:延迟> | <例如:每分钟 500 单时,结账 p95 低于 2 秒> |
| 3 | <例如:可变更性> | <例如:上线新的支付方式无需改动订单服务> |
## 3. 约束
不是我们选的,但必须接受的东西。
- <例如:运行在公司的 Kubernetes 平台上>
- <例如:客户数据留在欧盟境内>
- <例如:后端服务只用 Go 或 Java>
## 4. 架构
**容器图(C4 第 2 层)**
<链接或嵌入。每个可部署单元和数据存储,标明技术和协议。>
| 容器 | 技术 | 职责 | 负责人 |
|---|---|---|---|
| <Web 应用> | <React SPA> | <做什么> | <团队> |
| <API> | <Go> | <做什么> | <团队> |
| <数据库> | <PostgreSQL> | <存储什么> | <团队> |
**组件图(C4 第 3 层)**
<只为新人最难理解的一两个容器画。链接或嵌入。>
**关键流程**
<最重要的两三个场景,用编号步骤或 C4 动态图表示。>
1. <参与者> -> <容器>:<发生了什么>
2. <容器> -> <容器>:<发生了什么、协议、同步还是异步>
## 5. 关键决策
完整记录位于 <docs/adr/>。这里是索引。
| ADR | 决策 | 状态 | 日期 |
|---|---|---|---|
| [ADR-001](adr/001-<slug>.md) | <例如:每个服务一个数据库> | 已采纳 | <YYYY-MM-DD> |
| [ADR-002](adr/002-<slug>.md) | <例如:订单事件使用 Kafka> | 已采纳 | <YYYY-MM-DD> |
## 6. 横切关注点
整个系统如何处理每个容器都会涉及的事情。每项一两行,并附上详细说明的链接。
- **认证与授权:** <在哪里进行,用什么令牌>
- **可观测性:** <日志、指标、链路追踪,去哪里看>
- **错误处理与重试:** <约定、幂等性>
- **数据与隐私:** <个人信息存放位置、保留期限>
## 7. 部署与运维
- **环境:** <生产、预发布、……>以及它们的差异
- **运行位置:** <云、区域、集群>
- **运维手册:** <链接>
- **仪表盘与告警:** <链接>
## 8. 风险与技术债务
| 风险或债务 | 一旦发生的影响 | 计划 | 负责人 |
|---|---|---|---|
| <例如:支付前预留库存,没有补偿机制> | <支付失败后留下幽灵预留> | <增加失败时释放,第四季度> | <团队> |
## 9. 术语表
| 术语 | 在这里的含义 |
|---|---|
| <订单> | <按业务中使用的含义给出的定义> |
模板就是这么多。对于一个有十来个容器的系统,填完通常只有几页。如果你的文档长得多,很可能有些内容应该放进链接的其他文档,而不是这一份。
逐章节说明
文档头:负责人和评审日期
顶部这四行比下面任何一个章节都重要。负责人说明文档出错时由谁来修正。上次评审告诉读者可以在多大程度上信任它。一份写着"上次评审于十四个月前"的文档是诚实的;一份什么都不写的文档,看起来是最新的,实际上却不是。
1. 上下文与范围
从这里开始,因为其他所有章节都依赖于这条边界。列出每一类用户和每一个外部系统,包括那些你觉得理所当然的(身份提供商、邮件服务、支付网关)。不在范围内这份清单能省掉的会议比文档里任何其他内容都多:在这里写明这个系统不处理退款,即使所有人都以为它会处理。
这张图是 C4 系统上下文图:你的系统是一个方框,用户和外部系统围在四周,箭头带有标签。系统上下文图指南介绍了图上应该放什么。
2. 质量目标
大多数架构文档都跳过了这一节,而它恰恰是解释其余一切的那一节。"可用性优先于一致性"或"可变更性优先于纯粹的性能",能让读者明白容器为什么是现在这个样子。目标控制在三到五个,排好优先级,并给每个目标配一个具体到可以测试的场景:一个数字、一个负载、一次故障。
3. 约束
约束是别人替你做的决定:平台团队、法务、公司的编程语言政策。把它们写下来,就能省掉"你为什么不直接用 X?"这样的对话,也能告诉未来的读者哪些选择可以重新考虑,哪些不能。
4. 架构:C4 图
大多数人一提到"架构",想到的就是这一节。使用 C4 模型,因为它让每张图只承担一项任务:
- 容器图(第 2 层),必画。 每个可部署单元和数据存储都标明技术,每条箭头都标明协议。如果你只画一张图,就画这一张。容器图指南中有一个实战示例。
- 组件图(第 3 层),有选择地画。 只为新人最难理解的容器画。
- 关键流程。 用编号步骤写出两三个场景。静态图展示两个容器之间有通信;流程则展示通信的顺序,以及用户要等待哪些步骤。C4 动态图指南介绍了如何编写。
容器表中带有负责人一列是有意为之。没有负责人的容器,在这份文档里也不会有人去更新。
如果你刚接触 C4,C4 模型是什么解释了四个层级。想看这些图应用到真实大型系统上的例子,请参阅我们的 C4 模型示例。
5. 关键决策(ADR)
不要把决策直接写在正文里。把每个决策作为一条架构决策记录保存在单独的文件中(背景、决策、考虑过的替代方案、后果),这里只保留索引。ADR 写完后不再修改,而是用新的 ADR 取代,这样文档保持简短,历史也完整保留。架构决策记录完整指南介绍了格式,以及什么样的决策值得写一条 ADR。
检验索引的一个好方法:新工程师指着第 4 节里任何一个让人意外的方框,都应该能找到解释它的那条 ADR。
6. 横切关注点
有些东西不属于任何一个容器:认证、日志、错误处理、个人数据存放在哪里。每项一两行,加上详细说明的链接就够了。审计人员在这一节花的时间最多,所以让他们看起来轻松些。
7. 部署与运维
保持简短,并链接出去。环境及其差异、系统运行在哪里,以及运维手册和仪表盘的链接。细节属于你的基础设施代码和运维手册,它们的变化频率本就应该比这份文档更高。
8. 风险与技术债务
这是诚实的一节。写下已知的脆弱之处,附上负责人和计划,哪怕计划是"已接受,第三季度再看"。写下来的风险,是有人能够排定优先级的风险;只存在于某位工程师脑子里的风险,会随着他一起离开。
9. 术语表
每个系统都有一些在这里有特定含义的词:「订单」与「购物车」,「账户」与「租户」,「履约」。每个词只定义一次。新工程师读这一节的次数会比你想象的多。
与 arc42 的关系
如果这份模板看起来眼熟,那是因为它是对 arc42 同一套理念的精简提炼。arc42 是由 Peter Hruschka 和 Gernot Starke 创建的免费开源架构文档模板,有十二个章节,它自己也建议"只记录你的利益相关者需要的内容"(arc42 FAQ,B-1)。对应关系如下:
| 本模板 | arc42 章节 |
|---|---|
| 1. 上下文与范围 | 1 Introduction and Goals(目的)、3 Context and Scope |
| 2. 质量目标 | 1 Introduction and Goals(质量目标)、10 Quality Requirements |
| 3. 约束 | 2 Constraints |
| 4. 架构 | 4 Solution Strategy(简要)、5 Building Block View、6 Runtime View |
| 5. 关键决策 | 9 Architecture Decisions |
| 6. 横切关注点 | 8 Crosscutting Concepts |
| 7. 部署与运维 | 7 Deployment View |
| 8. 风险与技术债务 | 11 Risks and Technical Debt |
| 9. 术语表 | 12 Glossary |
当你需要 arc42 的完整结构时就选 arc42:受监管的环境、有多位架构师的大型系统,或者已经以 arc42 为标准的组织。当另一个选项是根本没有文档时,就选这种规模的模板。更详细的对比,包括哪张 C4 图放进 arc42 的哪个章节,请参阅 arc42 vs C4。
避免文档过时
每一份架构文档在合并那天都是准确的。六个月后是否依然准确,取决于几个习惯,其中大部分和图有关,因为第 4 节和第 5 节是现实变化最快的地方。
放在代码仓库里。 docs/architecture.md 和代码放在一起,意味着一个拆分服务的拉取请求可以在同一次评审中更新容器表。Wiki 页面无法成为代码评审的一部分。
链接图,不要贴截图。 容器图的截图在容器改名的那一刻就过时了。从模型渲染的图(Structurizr DSL、YAML 模型,或者保存模型的工具)只会和模型一样新或旧。
让评审日期真正发挥作用。 把这份文档加进每次新增或删除容器时都会走的检查清单:拉取请求模板、架构评审、季度规划。"下次评审:每次修改第 3 到 5 节时"也是一个有效的写法。
决策只往前写。 永远不要修改已采纳的 ADR,而是取代它。这样第 5 节的索引就能呈现历史,而这正是大家最需要的部分。
自动检查结构性内容。 第 1 节和第 4 节描述的是代码中真实存在的东西:服务、数据存储、依赖。它们可以和代码仓库进行比对。第 2、6、8 节则不行,需要有人按计划评审。架构漂移检测指南介绍了前一类的检测方法,以及每种方法能看到什么、看不到什么。
这正是 archyl 针对文档中"图"这一半所要解决的问题。连接一个代码仓库,AI 发现会提出 C4 模型(系统、容器、组件和关系),由你审阅和批准,而不必亲手去画。ADR、文档和流程会链接到它们所描述的元素上。之后,漂移评分会以确定性的方式、在不经过 AI 的情况下,检查文档中的元素是否仍然存在于代码中,于是过时的第 4 节会以一个数字的形式显现出来,而不是某天突然给你一个意外。它不会检查你的质量目标或风险清单,这些仍然需要评审日期来保障。关于无论有没有工具都能让文档保持最新的实践,请参阅活的架构文档。
常见问题
软件架构文档应该包含什么?
至少包括:系统的上下文与范围(用户和外部系统)、标明技术的容器级图、附带理由的关键架构决策、已知风险,以及负责人和评审日期。上面的模板还增加了质量目标、约束、横切关注点、部署说明和术语表,每一项都很简短。
这个模板真的免费吗?
是的。就是上面那个 Markdown 代码块。复制下来,按你的系统修改即可。无需注册,无需下载,也不用留邮箱。
架构文档应该放在哪里?
放在代码仓库里,命名为 docs/architecture.md 或 ARCHITECTURE.md,与 docs/adr/ 中的 ADR 放在一起。这样,架构的变更和文档的变更会经过同一个拉取请求。
架构文档应该写多长?
在回答读者问题的前提下,越短越好。对于一个有十来个容器的系统,几页是正常的。如果远远超出这个篇幅,就把细节移到链接的文档中(运维手册、ADR、API 参考),让这份文档保持为一张地图。
它和系统设计文档有什么区别?
系统设计文档通常是为某个项目或功能、在构建之前编写的,包含详细设计。架构文档描述的是整个系统当前的样子,并随系统一起变化。团队通常每个系统有一份架构文档,在其生命周期中会有许多设计文档,而设计文档中那些长期有效的决策,最终会变成 ADR。
我应该改用 arc42 吗?
如果你需要它的完整结构,或者你的组织已经在用它,那就用。本模板与 arc42 的章节一一对应(见上表),所以你可以先从这里开始,之后再扩展到 arc42,而无需重写任何内容。
想让第 4 节里的图来自你的代码,而不是来自记忆?在 Developer 计划下免费试用 archyl,无需信用卡。继续阅读:arc42 vs C4 | 架构决策记录:完整指南 | 什么是 C4 模型? | 活的架构文档 | 架构漂移检测