架构决策记录(ADR)实践:从一张白纸到可追溯的架构演进
架构决策记录(ADR)是记录架构决策的轻量级方法,解决"为什么这么设计"的问题。本文从 ADR 的格式、编写时机、管理方式三个层面展开,给出一个可直接套用的 ADR 模板和团队落地建议——适合正在或准备引入架构决策记录的团队。
先说结论:ADR 是写给未来自己的信
每个团队都遇到过这样的问题:半年后回看自己的代码,想不通为什么当初选了某个方案。代码里看不出决策上下文,PR 描述里只写了”改成 X”,但没人记得为什么不用 Y。
ADR(Architecture Decision Record)就是解决这个问题的——它用轻量级的 Markdown 文件记录每次架构决策的上下文、备选方案和最终选择。
1. ADR 的格式
推荐模板
# [编号]. [标题]
日期:[YYYY-MM-DD]
## 状态
[Proposed | Accepted | Deprecated | Superseded]
## 上下文
[描述需要做决策的背景。为什么这个决策是必要的?当前系统有什么问题?]
## 决策
[我们决定做什么。用陈述句,不用"考虑"、"可能"这类模糊词汇]
## 备选方案
- [方案 A]:[优点和缺点]
- [方案 B]:[优点和缺点]
- [方案 C]:[优点和缺点]
## 后果
[这个决策带来的正面和负面影响。包括技术债务、迁移成本、学习曲线等]
## 兼容性
[这个决策是否影响现有系统?是否需要迁移?是否有兼容期?]
示例
# 1. 使用 PostgreSQL 作为主数据库
日期:2026-07-16
## 状态
Accepted
## 上下文
我们需要为新的 Token 交易平台选择主数据库。需求包括:ACID 事务支持、JSON 字段存储、复杂查询和报表。团队熟悉 SQL。
## 决策
使用 PostgreSQL 16 作为主数据库。
## 备选方案
- MySQL 8.0:ACID 支持成熟,但 JSON 查询能力不如 PostgreSQL,且缺少窗口函数等高级分析功能
- MongoDB 7.0:NoSQL 灵活,但不支持跨文档事务(在需要强一致性的场景下有问题)
- TimescaleDB:时序场景优秀,但作为通用场景的主数据库不够成熟
## 后果
正面:团队不需要学习新查询语言,PostgreSQL 的 JSON 和窗口函数满足 Token 平台的查询需求
负面:相比 MySQL,PostgreSQL 的运维工具链稍弱,需要额外配置监控和备份
## 兼容性
新系统,无历史数据迁移问题
2. 什么时候写 ADR
需要写 ADR 的场景
- 引入新的技术栈或框架
- 改变模块之间的通信方式(如 REST → 消息队列)
- 确定数据存储方案(PostgreSQL vs MongoDB)
- 确定系统部署方式(Docker Compose vs K8s)
- 改变系统的安全策略(认证方式、权限模型)
不需要写 ADR 的场景
- 日常的 bug 修复
- 小范围的重构(函数重命名、提取公共方法)
- 技术选型已经在 ADR 中覆盖过的重复决策
3. ADR 的管理
目录结构
docs/adr/
README.md # ADR 索引
0001-use-postgresql.md
0002-use-docker-compose.md
0003-use-jwt-auth.md
索引文件示例
# 架构决策记录
| 编号 | 标题 | 状态 | 日期 |
|------|------|------|------|
| 1 | 使用 PostgreSQL 作为主数据库 | Accepted | 2026-07-16 |
| 2 | 使用 Docker Compose 部署 | Accepted | 2026-07-17 |
| 3 | 使用 JWT 认证 | Superseded → 4 | 2026-07-18 |
| 4 | 使用 Session + Redis 认证 | Accepted | 2026-07-20 |
生命周期
Proposed → Accepted → Deprecated
→ Superseded → (新 ADR)
总结
| 层面 | 核心原则 | 常见错误 |
|---|---|---|
| 内容 | 只记决策,不记实现 | 写成技术文档 |
| 时机 | 做决策时写,不事后补 | 几个月后补写,回忆不准确 |
| 位置 | 和代码在一起,随 PR 提交 | 放在 Wiki 或共享文档中,没人维护 |
| 管理 | 维护索引、状态、决策链 | 写一次就不管了,状态永远不更新 |
ADR 的价值不在于”写了多少份”,而在于”半年后还能看懂当初为什么这么选”。 一个维护良好的 ADR 仓库,比任何架构文档都更能反映系统的真实演进过程。
需要架构评审或技术方案咨询?联系我们,说清你的系统现状与决策需求,24 小时内回可行性。
相关阅读
- 技术方案评审怎么做:选型、架构评审与可行性报告的方法 —— ADR 的上游技术决策流程
- 微服务拆分与演进:从单体到服务化的工程决策框架 —— ADR 在架构演进中的记录实践
常见问题
ADR 和普通技术文档有什么区别?
ADR 只记录决策,不记录实现细节。普通技术文档描述"系统是怎么工作的",ADR 描述"为什么这样做"。两者的区别在于:实现细节会随着代码变更而失效,而决策理由(上下文、备选方案、权衡)几乎不会过时。ADR 是写给未来的自己看的——半年后你回来看一个决策,ADR 能告诉你当时为什么选了 A 而不是 B。
ADR 应该什么时候写?
每次做出一个架构决策时写,而不是事后补。什么时候算"架构决策"?① 引入新的技术栈或框架;② 改变模块之间的通信方式(如从 REST 改为消息队列);③ 决定数据存储方案(如选 PostgreSQL 还是 MongoDB);④ 确定系统的部署方式(如选 Docker Compose 还是 K8s)。小决策(如某个函数用什么算法)不需要 ADR。
ADR 应该存放在哪里?
和代码放在一起,用 Markdown 格式,存放在 docs/adr/ 目录下,文件名格式为 NNNN-title-with-dashes.md。和代码一起版本管理,随 PR 提交。这样做的好处是:ADR 和代码变更一一对应,git blame 可以追溯到具体的决策和修改。
ADR 写多了怎么管理?
维护一个 ADR 索引文件(README.md),列出所有 ADR 的编号、标题、状态和日期。按状态分类:Proposed(提案中)、Accepted(已接受)、Deprecated(已弃用)、Superseded(被替代)。被替代的 ADR 用 Superseded-by 字段指向新 ADR,形成决策链。