ADR 是什么
架构决策记录(ADR,Architecture Decision Record)用一页短文档记下一次重要架构决策:当时面对什么背景、最终决定怎么做、比较过哪些备选方案、预期要付出什么代价。该做法由 Michael Nygard 在 2011 年提出,核心主张是决策记录与代码放在同一仓库并顺序编号,逐步积累成可追溯的决策日志。它的价值不在于描述系统长什么样,而在于解释为什么变成现在这样,让后来者能分清哪些是刻意设计、哪些是历史遗留。
基本信息
| 载体 | Markdown 单文件,与代码同仓库、同评审 |
|---|---|
| 编号与状态 | 顺序编号;状态含 proposed / accepted / superseded / deprecated |
| 记录内容 | 背景、决策、备选方案与放弃原因、后果 |
| 粒度 | 一次决策一篇;跨系统总体设计另写设计文档 |
| 存放位置 | 仓库内固定目录(如 docs/adr/),便于检索引用 |
典型使用场景
- 技术选型定稿:把数据库、消息中间件、IaC 工具的取舍写成可引用的记录
- 引入或替换关键组件:写清迁移窗口、双跑方案与回退路径
- 划定服务边界与数据归属:记录拆分理由,避免同类争论反复发生
- 确定接口兼容策略:版本号规则、弃用流程与下线时间点
- 记录被否决的方案:防止半年后有人重新提出已被否定的思路
- 沉淀口头共识:新成员靠阅读决策历史就能理解现状与约束
模板示例
模板示例
# ADR-0012 订单与库存域采用事件驱动集成
## 背景
订单创建后需通知库存锁定,两个域由不同团队维护
## 决策
通过消息中间件发布领域事件,消费方按消息 ID 幂等处理
## 备选方案
- 同步 RPC 调用(放弃:把两个域的可用性绑在一起)
- 共享数据库表(放弃:破坏数据归属,无法独立演进)
## 后果
收益:解耦部署、可削峰;代价:最终一致,需要补偿与对账
## 状态
accepted(2026-10-13),取代 ADR-0007一条决策的要素
| 要素 | 写什么 | 常见问题 |
|---|---|---|
| 标题 | 一句话说明决策与范围 | 标题含糊,从目录看不出讲了什么 |
| 背景 | 问题、约束、当时的痛点 | 只写结论不写约束,后来者无法判断前提是否还成立 |
| 决策 | 选定方案与生效范围 | 写成待办清单,缺少明确结论 |
| 备选方案 | 被比较、被否决的方案及原因 | 只列方案不写否决理由,等于白记 |
| 后果 | 获得的收益与新增的成本、风险 | 只写好处,回避复杂度与运维代价 |
ADR 的状态要跟着现实走:方案被替换时不要删旧文件,而是把旧记录标为 superseded 并链接到新编号;历史链条一旦断掉,追溯价值就没了。
ADR 与设计文档分工不同:ADR 回答为什么这样选,控制在一页以内;接口细节、时序图与部署拓扑放在设计文档里,避免把 ADR 写成大而全的方案书。