跳到主要内容

从约束到架构决策记录

架构决策记录(ADR)保存一个重要技术选择的上下文、备选方案、决定和后果,让团队能够理解并验证当时的取舍。

1. 识别值得记录的决策

ADR 适合影响广、代价高或以后难以逆转的选择,例如:

  • 单体、模块化单体或微服务的边界;
  • 数据存储、一致性和跨地域方案;
  • 对外 API、事件和身份协议;
  • 高可用、安全和合规策略;
  • 核心框架、运行平台与构建方式。

普通实现细节和容易回退的局部改动可以留在代码评审中。每个小选择都写 ADR,会让决策日志充满噪声;关键决定没有记录,则会让后来者只能从代码猜测原因。

判断方法是:如果一年后有人想改掉它,是否需要知道当时的业务约束和被放弃的方案?答案为是,就值得记录。

2. 约束先于方案

决策从问题和约束开始。约束可以来自:

  • 目标用户量、延迟和 SLO;
  • 数据一致性、隐私和地域要求;
  • 交付期限、预算和可用人力;
  • 现有系统、迁移窗口和兼容期限;
  • 团队技能、值班和平台能力;
  • 供应商限制与退出成本。

约束要尽可能量化。“高性能”无法筛选方案,“P99 低于 200 ms,峰值每秒 5000 次请求”才可以。仍不确定的内容标为假设,并写出验证方法。

如果评审直接从“用 Kafka 还是 RabbitMQ”开始,团队很容易比较功能清单,却忘记要解决的问题。

3. 备选方案使用同一组标准

至少保留一个可行替代方案和“维持现状”。对每个方案按同一维度比较:

  • 是否满足必须约束;
  • 实现、迁移和学习成本;
  • 运行、故障和安全风险;
  • 可观测性与验证方式;
  • 可逆性、锁定和退出成本;
  • 对未来变化的影响。

关键结论需要证据,例如原型、压测、故障注入、供应商文档或现网数据。无法在当前阶段验证的风险要显式保留,不能用主观评分制造确定感。

对明显不满足硬约束的方案,可以说明原因后提前淘汰,不需要写成同样长度。

4. ADR 保持短而完整

一份 ADR 至少包含:

# 标题

- 状态:Proposed / Accepted / Superseded
- 日期:
- 负责人:

## 上下文与问题
## 约束与假设
## 考虑过的方案
## 决定
## 后果
## 验证与复审条件

“决定”要写清选了什么和适用范围;“后果”同时记录获得的能力、承担的成本和后续工作。ADR 解释为什么做出选择,详细实现放到设计文档和代码中。

标题直接写结论,例如“订单事件采用 transactional outbox 发布”,比“消息方案选型”更容易浏览决策日志。

5. 决策状态保留演进关系

ADR 可以经历 Proposed、Accepted、Rejected、Deprecated 和 Superseded 等状态。团队接受后,不直接改写原记录来适配新结论。

新证据出现时,新建 ADR 并链接被替代记录。这样可以看到:

  • 原决定在什么约束下成立;
  • 哪项约束或证据发生了变化;
  • 新决定从何时开始生效;
  • 哪些系统仍处于迁移期。

草案阶段可以正常修改。接受后只修正链接和明显文字错误,结论变化通过新记录表达。

6. 决策连接到验证

ADR 不是评审结束后的存档。它应连接到:

  • 原型、基准和风险验证任务;
  • 实现 issue 与代码评审;
  • SLO、成本和业务指标;
  • 迁移阶段、回滚和退出条件;
  • 需要复审的日期或触发事件。

例如选择异步复制以降低写延迟,就应记录允许的 RPO、复制延迟告警和灾后对账方案。指标长期超出边界时,自动触发复审比等到故障后重新争论更有效。

架构测试也可以验证决定,例如禁止模块依赖环、限制数据库访问或检查 API 兼容性。

7. 评审关注未知风险

ADR 评审先确认问题、约束和决策负责人,再讨论方案。评论需要指出具体风险、缺失证据或冲突约束;“我更喜欢另一个框架”不构成阻塞理由。

无法达成一致时,由事先明确的决策负责人基于现有证据决定,记录少数意见和需要观察的风险。重大安全、合规或不可逆数据风险则由相应责任人拥有否决权。

评审时间也要有边界。可逆决策可以用小实验快速验证;高代价不可逆决策需要更充分的证据和更广的参与者。

8. 一个简化示例

订单服务需要可靠发布领域事件,约束是数据库提交与事件不能永久分离、现有团队只运维 MySQL 和 Kafka、允许秒级发布延迟。

备选方案包括数据库与 Kafka 分布式事务、业务代码直接双写,以及 transactional outbox。团队选择 outbox,因为它利用本地事务保证业务记录和待发事件共同提交,发布器可以重试;代价是消费者必须幂等、需要清理事件表并监控发布延迟。

验证项包括故障注入、重复事件测试和发布延迟 SLO。若未来数据库原生 CDC 成为统一平台能力,再复审发布器实现。

9. 面试题

9.1 做技术选型时怎样形成可追溯的架构决策

出现公司:字节跳动

考察重点

  • 问题、硬约束、假设和证据。
  • 备选方案、后果与可逆性。
  • ADR 生命周期、验证和复审条件。

相关内容:第 1 节“识别值得记录的决策”至第 7 节“评审关注未知风险”。

参考回答

我会先写清业务问题、成功指标和必须满足的约束,把不确定内容标成假设。然后让维持现状和其他可行方案按相同标准比较,包括功能、迁移、运行风险、成本、可逆性和退出代价;关键结论用原型、压测或现网数据验证。

最终 ADR 记录上下文、约束、方案、决定、正负后果、负责人和验证条件。决定接受后保持原记录稳定,未来约束变化时用新 ADR 替代并建立链接。实现任务、指标、迁移和架构测试都关联到决定;无法共识时由明确的决策负责人判断,同时保留异议和需要继续观察的风险。