首页/开发/系统分析与架构设计速查/架构决策记录(ADR)

架构决策记录(ADR)

用短文档记录单条架构决策:背景、决策内容、备选方案与后果;ADR 按编号归档并纳入代码库评审,让后来者理解决策的来龙去脉。

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 写成大而全的方案书。

易错点

  • 决策只在会议或即时通讯里达成,没有落盘:人员变动后约束与前提无人知晓
  • 把 ADR 写成事无巨细的长文档,维护成本高,写几篇后整队弃用
  • 只记录最终方案、不记录被否决方案:同类提案反复讨论,评审成本重复支出
  • 决策变更后直接改写旧记录:历史被覆盖,无法解释某段时间系统为何处于那个状态
  • ADR 与代码分离存放:评审时不看,代码改了记录不动,很快过期失效

数据来源与参考

  • Michael Nygard:Documenting Architecture Decisions(2011)
  • adr.github.io:Architecture Decision Records
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌