3179 字
约 10 分钟
13
S03-A14 · 架构与现实的对齐:设计意图和实际运行差在哪

架构评审的 PPT 上画着三个服务,线上跑着十一个。多出来的八个没有一个是"设计过的":两个是某次大促的临时扩容没回收,三个是"先这么接一下"的旁路,两个是把定时任务包成了服务,还有一个没人说得清来历,但所有订单都要经过它。

这类偏离不会自己暴露。图画得越漂亮,偏离越难被发现——因为没人会拿生产流量去核对一张幻灯片。对齐检查要做的不是重画架构图,而是让实际形态留下证据,然后把证据和意图之间的差写成待办。


1. 偏离的四个来源

来源 形成方式 典型时间尺度 可识别信号
临时方案固化 应急上线,事后无人回收 数周到数月 名字带 temp/old,无 owner
绕过路径 主链路不通,另起一条 数天 同一业务有两条写入路径
配置漂移 手工改配置、环境不一致 逐次累积 环境行为不同,配置不在仓库
代码腐化 边界被逐步越过 数季 依赖方向与设计文档相反

四者的共同点是每一步都合理:应急上线是当时最优解,旁路是当时唯一能通的路。所以纠偏不能追问"当初为什么",只能看"现在这条路径还有没有人认领"。


2. 偏离本身不是问题,未记录才是

系统演化必然产生偏离,把偏离清零既不现实也不经济。判别标准只有一条:这个偏离是否在某人脑子里有记录、有 owner、有失效条件。

状态 定义 风险
已记录 + 有 owner 写在 ADR 或清单里,知道为何存在 低,可管理
已记录 + 无 owner 写了,没人负责回收 中,会过期
未记录 + 有 owner 只有一人知道 高
未记录 + 无 owner 无人知道为何存在 最高,无人敢动

对齐检查的产出就是把第三、四类变成第一类:不消灭,先让它可见。


3. 看流量与依赖,不看图

证据源 能回答 盲区
调用链(trace) 谁真的调谁、耗时分布 异步与消息链路常缺失
依赖清单(运行时) 连了哪些下游 看不见"该连而没连"
配置快照 实际生效的参数 配置中心改过的不在快照里
网关日志 外部真实调用面 内网直连绕过网关

四个源要交叉:trace 给主链路,网关给对外面,配置快照给行为差异。单独任何一个都会给出看起来很完整的错误答案——只看 trace 会以为某服务已下线,实际仍有批处理在调它。

// 依赖清单的最小取法(按环境分别取,不要只看一个)
ss -tnp state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn
// 输出:每个下游 IP 的活跃连接数
// 用途:和 trace 里的调用方列表做差集,差集就是"未被观测到的依赖"

4. 临时方案的三个特征

特征 检测方式 为什么危险
没有名字 服务名是 IP、随机串、人名拼音 无法被检索,等于不存在
没有 owner 无 CODEOWNERS、工单无人认领 出事无人敢改
无文档但在关键路径 trace 频次高、文档没有 影响面未知,变更即盲改

三条同时成立时,它的实际地位是"影子核心系统":不在图上,失效即停摆,也是复盘里最常见的"没想到它这么关键"。

判据很直接:在关键路径上、但不在任何清单里的组件,优先于任何优化项处理。 先给它名字和 owner,再谈别的。


5. ADR 与实现的一致性检查

ADR 记录的是决策,代码记录的是结果。两者会分叉,分叉点就是偏离点。

─── 每个 ADR 至少要能被问三个问题
1) 决策里写的约束,现在是否还成立?(如"只允许同步调用")
2) 决策里写的例外,是否已经变成常态?(如"临时允许直连 DB")
3) 若今天重做这个决策,前提是否变了?(如流量量级、团队规模)
// 三个问题里有一个答"变了",这个 ADR 就该被更新或废止
// 注意:ADR 不更新不是文档问题,是决策失效而无人知晓

常见失效:ADR 写着"服务间只走 HTTP,不允许共享数据库",两年后三个服务直连同一库,没人记得有过这条。不是执行不力,是没有检查点。


6. 检查频率与成本

方式 成本 覆盖 漏什么
全量手工盘点 数人日,季度级 全面 盘点完就过期
抽样 trace 复核 半天,月度 主链路 低频与异步路径
自动化依赖断言 一次性投入 + 维护 代码内可见的边界 运行时与基础设施层
事故驱动复核 几乎为零 出问题的地方 一切没出问题的地方

组合才有效:断言守代码内边界,月度抽样看运行时,复盘补盲区。 全量盘点当常规动作是浪费,产出完成当天就开始贬值。

─── 一份可执行的检查节奏
月度: 抽 3 条主链路 trace,对一遍依赖清单
季度: 配置快照 diff(prod vs stage),差异逐条写原因
每次事故: 复盘补一问——哪个未记录偏离放大了它
每年: 过一遍 ADR,回答三个问题,废止或更新

7. 偏离的三种处置

处置 成本 适用 风险
承认并记录 最低(写一条) 短期、影响可控 无人回访则变永久
纳入设计 中(改图、改基线) 已验证有效、长期存在 把技术债洗成设计
消除 高(改造、下线) 关键路径且无人负责 改造风险高于偏离本身

判据是影响面 × 无人负责程度:影响大且无人负责的必须消除,影响小且有人负责的登记即可。最危险的是把第二项当第一项用——"纳入设计"让问题从待办消失,却没支付任何成本。


8. 架构守护的自动化手段

手段 拦住什么 维护成本
依赖规则(禁止 A→B) 分层违规、循环依赖 低,规则少而稳
分层断言(controller 不碰 dao) 越层调用 中,重构期频繁误报
边界检查(API 清单) 内部实现被外部依赖 中,需随契约更新
命名/包结构约定 结构漂移 低,易形式化空转
// 守护断言的写法要点:断言"禁止什么",而不是"必须长什么样"
noClasses().that().resideInAPackage("..domain..")
    .should().dependOnClassesThat().resideInAPackage("..web..")
// 理由:禁止式断言在架构演进时仍然成立,形状式断言会锁死设计
// 维护规则:每条断言写明引入原因与失效条件,否则三年后没人敢删

自动化的价值是把"对齐"从事后盘点变成持续约束,代价是它只看得见代码里写出来的关系:基础设施偏离与跨进程旁路,一条都拦不住。


9. 产物是待办条目,不是报告

最常见的失败形态:产出三十页现状报告,会上宣讲后归档,三个月后没人打开。

有效的产物只有一种形态——可指派的条目:

─── 一条合格的偏离条目
偏离: 订单查询存在直连 DB 的旁路(绕过 order-service)
来源: 2024 年大促应急
证据: trace 中 12% 的查询来自 batch-worker 直连
影响: 分库后该路径会失效,影响面未知
处置: 登记(短期)→ 纳入设计(Q2 评估)→ 消除(分库前必须)
owner: @order-team
失效条件: 若 batch-worker 在分库前下线,本条自动关闭

判据:条目数不是产出,被指派且有失效条件的条目数才是。 没有 owner 的条目会沉淀成第二份报告。


10. 度量:四个数

指标 定义 读法 误读风险
未记录偏离数 检查发现的无记录项 真实债规模 只统计被看见的
临时方案数 名字含 temp/old 且无 owner 影子系统规模 改名即可规避
依赖违规数 断言命中的条数 边界守得住吗 规则太严时虚高
对齐到处置时长 从发现到有 owner 的天数 机制是否在转 快速关闭可能只是标记
// 判读顺序
1) 未记录偏离数下降而临时方案数不降 → 登记了但没处置
2) 依赖违规数下降但架构没变 → 规则被放宽或断言被跳过
3) 对齐到处置时长上升 → 检查产出的条目没人接,机制空转

第二个是指标自噬:违规数好看,通常意味着约束被删掉,而不是结构变好。


11. 排错:五种"检查做了但没用"

现象 真实原因 处理
报告很厚没人动 产物不可指派 条目 + owner + 失效条件
每次结论都一样 只看代码,没看运行时 加 trace 与网关日志
图更新了,事故照旧 图是意图,证据是流量 以流量为准重画
断言误报被关掉 规则按形状写死 改写禁止式断言
临时方案越查越多 检查口径包含所有旁路 只统计关键路径上的

最后一条值得强调:把全部旁路列进清单会让清单失去优先级。只把"关键路径且无 owner"的算必须处理,其余登记备查。


12. 边界:什么时候不必做正式对齐

场景 值得做吗 理由
单体、单进程部署 不值得 编译器保证依赖,无跨进程偏离
代码小到能一次读完 不值得 全员共享同一份心智模型
团队与系统规模匹配 收益低 偏离还在人的记忆里
刚上线、组件数稳定 收益低 偏离尚未固化
多团队、组件数持续增长 值得 心智模型开始分叉
已出现说不清来历的组件 值得 影子系统已存在

判据:当"系统是什么样"已不能靠一个人的记忆回答时,对齐检查才有收益。 在那之前,它只是给所有人都清楚的事实补一份文档。


13. 自测

  1. 图上三个服务、线上十一个,多出来的八个最可能来自哪几类来源?
  2. 为什么"已记录但无 owner"的偏离仍然算风险?
  3. 只看 trace 会漏掉哪类依赖?用什么补齐?
  4. 一个组件没名字、没 owner、却在关键路径上,先做什么?
  5. "纳入设计"这种处置为什么可能掩盖问题?
  6. 依赖违规数下降,怎么判断是结构变好还是约束被删?
S03-A14 · 架构与现实的对齐:设计意图和实际运行差在哪
https://www.clxhxhhr.top/posts/6307/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。