2. 架构决策的本质
架构决策不是“把系统画成几张图”,而是在约束条件下对系统长期形态做出承诺。要抓住它的本质,需要回答三个问题:什么时候出现了必须拍板的决策场景?这个决策属于架构层还是设计层?一旦做出,它有多难撤回、会影响多大范围?
一、识别决策场景:从“问题信号”到“待决事项”
决策场景通常不是凭空出现的,而是由一组信号触发。常见的触发信号包括:
- 质量属性冲突:例如“高并发写入”与“强一致读”同时被提出,二者在单库单表下难以兼得。
- 外部约束变化:合规要求数据不得出境、客户要求私有化部署、预算削减导致无法继续使用某商业中间件。
- 规模或边界变化:用户量从十万级跃升到千万级,或业务从单一租户扩展为多租户。
- 技术债显性化:某模块每次发布都要全量回归,故障恢复时间超过可接受阈值。
识别场景的关键动作,是把模糊的“我们得改改”转写为可决策的陈述。一个可决策的陈述至少包含:决策问题、候选方案、约束条件、评估维度。例如,把“订单系统太慢”转写为:“在日均 500 万订单、峰值 8000 TPS、允许最终一致的前提下,订单写入应采用分库分表还是事件溯源?”——这才构成一个可进入决策流程的场景。
二、架构决策与设计决策的分界
两者最容易混淆,因为都涉及“选型”和“取舍”。区分标准不是“谁做的”,而是影响范围、变更成本、约束强度三个维度。
| 维度 | 架构决策 | 设计决策 |
|---|---|---|
| 影响范围 | 跨多个模块、团队或系统边界 | 通常局限在单个模块或服务内部 |
| 变更成本 | 高,常涉及数据迁移、接口重写、部署重构 | 低,通常可在一次迭代内替换 |
| 约束强度 | 形成后续设计的强制前提 | 在既定架构约束下做局部优化 |
| 典型例子 | 服务拆分粒度、数据一致性模型、通信协议、部署拓扑 | 类职责划分、算法选择、缓存键设计、日志格式 |
需要强调的是,分界不是绝对的。一个设计决策如果被大量模块复用,也可能上升为架构决策;反之,架构决策在落地时会被拆解为若干设计决策。判断时问一句:“如果这个决定错了,重做它需要动多少东西?” 答案越大,越偏架构。
三、不可逆性与影响范围:决策的“重量”
架构决策的“重量”由两个轴决定:不可逆性(撤回难度)和影响范围(波及广度)。二者共同决定决策应投入的评审力度和记录详细程度。
- 高不可逆 + 大范围:如选择自研分布式存储、确定多租户隔离模型。这类决策一旦落地,迁移成本以人月计,必须做正式 ADR、多方案对比和风险预案。
- 高不可逆 + 小范围:如某边缘服务选用特定硬件加密卡。影响面窄,但更换代价高,需在采购前锁定。
- 低不可逆 + 大范围:如统一日志采集格式。影响广但可渐进替换,适合先试点再推广。
- 低不可逆 + 小范围:如某工具类库选型。可快速试错,不必上升到架构评审。
不可逆性常被低估。一个典型例子是“数据库选型”:如果初期选了不支持分布式事务的 NoSQL,后期业务要求跨实体强一致,改造成本远高于初期直接选关系型数据库。因此,对高不可逆决策,宁可前期多花时间做验证性原型(spike),也不要靠“以后再说”拖延。
四、把决策场景、层级与重量串起来
下面这张图把本节的核心关系组织为一条判断链:从触发信号识别场景,到按影响范围与变更成本区分层级,再到按不可逆性与影响范围评估决策重量,最终决定评审与记录方式。
图中最值得记住的是中间那条“转写”环节:很多团队跳过它,直接进入方案讨论,结果争论的是“用 A 还是用 B”,却没有先对齐“我们到底在解决什么问题、约束是什么”。把场景转写清楚,后续的层级判断和重量评估才有依据。
五、一个可操作的判断顺序
在实际评审中,可以按以下顺序快速判断一个议题是否属于架构决策:
- 它是否改变了系统边界或模块间契约? 若是,偏架构。
- 它是否约束了多个团队的并行工作? 若是,偏架构。
- 如果选错,重做需要多少人月? 超过一个迭代周期,偏架构。
- 它是否涉及数据模型、一致性、通信协议、部署拓扑? 这些通常是架构决策的高频领域。
反过来,如果一个问题只影响单个服务内部、可以在一次迭代内替换、不改变对外契约,那么它更适合作为设计决策,在团队内部快速拍板并记录即可,不必占用架构评审资源。
最后需要提醒:不可逆性并非一成不变。随着抽象层、适配层和自动化迁移工具的引入,某些原本高不可逆的决策可能变得可逆。因此,在评估决策重量时,除了看决策本身,也要看团队是否具备降低不可逆性的工程能力——这本身也是一个值得记录的架构决策。