架构决策方法:如何用 ADR 记录每一次取舍

上一篇文章中写了《架构师到底在做什么:从需求到上线的全链路责任》,这一篇讨论怎么记录架构决策。

架构设计中最容易丢失的,往往不是最终方案,而是决策过程。

记忆随着时间的推移是会模糊的,比如,半年后回看一个系统,大家通常只记得“我们用了 Kafka”“我们拆了微服务”“我们选了 Redis”,但很少有人能回答:

  • 当时为什么选它?
  • 有没有考虑过其他方案?
  • 放弃了什么?
  • 付出了什么代价?
  • 这个决策现在是否还成立?

如果没有记录,架构就会逐渐变成一堆“历史遗留决定”。ADR 就是为了解决这个问题。

一、什么是 ADR

ADR 全称Architecture Decision Record,即架构决策记录。

它不是详细设计文档,也不是需求文档,而是一份轻量、可追溯的决策快照,用来回答一个问题:

在某个时间点,我们为什么做出了这个架构选择?

一份合格的 ADR 应该让新加入的团队成员在十分钟内理解:当时发生了什么、为什么这样选、现在还能不能改。

二、为什么架构师必须写 ADR

很多团队的问题不是没有决策,而是决策只存在于会议纪要、聊天记录或某个人的脑子里。

时间一长,会出现三种典型问题:

  1. 新人看不懂现状
    看到一堆奇怪的配置、冗余的模块、过时的中间件,却不知道当初为什么存在。

  2. 重复讨论旧决策
    每次有人提出“要不要换成 X”,都要重新把半年前的争论再走一遍。

  3. 架构腐化无人负责
    系统逐渐偏离最初设计,但没有人能说清楚是从哪一步开始偏离的。

ADR 的价值在于:把架构决策从“拍脑袋”变成可复盘的工程资产。

三、ADR 应该包含哪些内容

一份实用的 ADR 不必复杂,但至少要包含以下要素:

字段 说明
编号 如 ADR-001,便于引用
标题 一句话概括决策内容
状态 Proposed / Accepted / Deprecated / Superseded
决策者 谁最终拍板
日期 决策发生的时间
背景 当时面临什么问题、有哪些约束
候选方案 列出至少两个可选方案
决策结果 最终选择了什么
决策理由 为什么选它,不选其他
代价与风险 这个选择带来了什么副作用
重新评估条件 什么情况下需要推翻这个决策

其中最重要的是:候选方案、决策理由、代价与风险。
只写“我们选了 Kafka”没有意义;写清楚“为什么没选 RabbitMQ / RocketMQ”才有价值。

四、一个 ADR 示例

ADR-001:设备上报通道选用 MQTT + Kafka

状态:Accepted
决策者:系统架构师
日期:20XX-XX-XX

背景

系统需要接入大量铁路信号设备上报数据,预计峰值 4 万点/秒。设备通过弱网环境连接,存在断线、重连、乱序、丢包等情况。后端需要保证数据不丢失、可重放,并支持后续流式处理。

候选方案

方案 优点 缺点
HTTP 直连后端 实现简单,团队熟悉 弱网下重连成本高,推送能力弱,设备端负担重
MQTT + RabbitMQ 设备接入成熟,运维相对简单 高吞吐场景下持久化消息能力弱,重放能力有限
MQTT + Kafka 高吞吐、可重放、适合流式处理 运维复杂度较高,Kafka 资源占用更大
TCP 长连接自研协议 完全可控 开发成本高,稳定性风险大,不利于后续扩展

决策结果

选用MQTT + Kafka作为设备数据上报通道。

设备端通过 MQTT Broker 接入,Broker 将消息转发至 Kafka Topic,后端消费 Kafka 进行清洗、存储和流式计算。

决策理由

  1. 设备接入层需要弱网友好
    MQTT 的 QoS、Last Will、断线重连机制更适合工业现场环境。

  2. 后端需要高吞吐与可重放
    Kafka 的顺序写入和分区模型能够支撑 4 万点/秒的写入压力,并且支持消息重放,便于数据回溯和故障恢复。

  3. 后续流式处理能力更强
    Kafka 可以与 Flink、Spark Streaming 等流处理框架自然衔接,适合后续做实时告警、趋势分析和容量预测。

  4. 团队具备中间件运维基础
    虽然 Kafka 运维复杂度高于 RabbitMQ,但团队已有容器化部署和监控经验,风险可控。

代价与风险

  • Kafka 集群运维成本高于 RabbitMQ;
  • 需要额外建设监控、告警和容量规划;
  • 初期小规模场景下可能显得“过重”;
  • 设备端需要适配 MQTT 协议,存量设备需通过网关转换。

重新评估条件

当出现以下情况时,应重新评估该决策:

  • 设备规模长期低于 5000 点/秒,且无流式处理需求;
  • 团队无法承担 Kafka 运维成本;
  • 业务转向强事务、低延迟命令下发,而非高吞吐数据上报;
  • 出现更合适的云托管消息服务,可显著降低运维负担。

五、ADR 的常见误区

误区一:把 ADR 写成详细设计

ADR 记录的是“为什么”,不是“怎么做”。详细实现应该放在设计文档、接口文档或代码注释里。

误区二:只记录最终方案

如果只写“我们选了 X”,那和没有记录区别不大。真正有价值的是被放弃的方案及其原因。

误区三:认为 ADR 一旦写下就不能改

ADR 不是圣旨。当业务、技术或团队条件变化时,可以新建一条 ADR 来取代旧决策,并把旧决策标记为Superseded或Deprecated。

误区四:追求完美格式而迟迟不动笔

ADR 最重要的是及时记录。哪怕最初只有背景、方案、理由三栏,也比事后回忆强得多。

六、如何在团队里落地 ADR

建议从三个动作开始:

  1. 建立 ADR 目录
    放在代码仓库或文档仓库中,例如 docs/adr/,按编号命名:001-mqtt-kafka-uplink.md。

  2. 规定触发条件
    不是每个小决定都要写 ADR,但以下情况必须记录:

    • 引入新的中间件或框架;
    • 改变系统边界或服务拆分;
    • 调整数据模型或核心接口契约;
    • 改变部署架构或运维方式;
    • 推翻之前的架构决策。
  3. 在代码评审中引用 ADR
    当有人质疑“为什么这么设计”时,直接给出 ADR 编号。这样既减少重复争论,也让新成员快速理解系统演进脉络。

七、总结

做架构设计不只是画出架构图就是完事了,还需要记录详细的架构决策。ADR就是这个好用的记录工具。

架构师的价值,不只体现在做出正确决策,更体现在让决策过程可被理解、可被质疑、可被迭代。

ADR 并不复杂,但它能把架构从“个人经验”变成“团队资产”。多年后,当你回头看一个系统,最珍贵的往往不是那张最终架构图,而是那些记录着“我们当时为什么这样选”的文字。

有了ADR,架构就是可推演的。你用过ADR吗?评论聊聊。

posted @ 2026-11-13 08:10  T-Evan  阅读(3)  评论(0)    收藏  举报