上一次线上事故的复盘结论是"缺少变更管控",于是所有变更都进了同一个审批流。三个月后,审批表从一页变成四页,审批人的平均处理时间从二十分钟变成三十秒——因为绝大多数条目都是"调超时""加日志级别"这类可秒级回滚的改动,过一眼就点同意。
流程加严了,风险却没有下降:真正的数据模型变更和一次超时调整走了同一条路,都被同一个人用同样的三十秒处理。
分级的本质是让审批成本跟着风险走,而不是跟着"制度存在感"走。
1. 先承认成本错配
| 变更类型 | 实际风险 | 统一审批下的处理 |
|---|---|---|
| 超时、日志级别、开关类配置 | 低,可秒级回滚 | 排队一到两天(典型量级),盖个章 |
| 依赖小版本升级 | 中,行为差异难预判 | 盖章通过,无人看变更说明 |
| 数据模型、字段语义变更 | 高,基本不可逆 | 盖章通过,风险与上一条相同 |
| 容量级变化(分片、副本数) | 高,影响面跨服务 | 盖章通过,无人算过容量 |
判断口径很直接:**审批时长与变更风险的相关性接近零,分级就已经失效。**此时流程只产出两样东西——延迟,和"已审批"的错觉。
2. 四类依据与组合判定
| 依据 | 判据问题 | 常见误判 |
|---|---|---|
| 影响面 | 出问题时谁受影响:单服务、跨服务、外部用户、收入 | 只看改了几个文件,不看调用方 |
| 可逆性 | 恢复要多久:秒级回滚、重新发布、人肉修数据 | 默认"能回滚",从未演练过 |
| 可观测性 | 好坏能否在分钟级看出来,还是只能等用户投诉 | 有面板不等于有判据 |
| 窗口 | 是否必须低峰、是否需要停机、是否与其他人冲突 | 把窗口当成"晚点做"的同义词 |
单维度判断必然出错,用组合规则可以把它变成查表:
组合判定(占位)
不可逆 + 影响面大 → 最高级(窗口 + 值守 + 演练记录)
不可逆 + 影响面小 → 次高级(事前审批 + 回滚方案)
可逆 + 影响面大 → 事前审批(观察指标必须写死)
可逆 + 可观测 + 影响面小 → 自动放行(只留记录)
可逆 + 不可观测 → 事后告知(必须补一个可观测点)
最后一行最容易被忽略:可逆但看不出来的变更,实际风险和不可逆一样——你会回滚一个本来不该回滚的东西,或者干脆不知道要回滚。
3. 四级模型与各自的证据要求
| 级别 | 触发条件 | 证据要求 | 谁看 |
|---|---|---|---|
| L0 自动放行 | 可逆 + 可观测 + 影响面小 | 流水线检查全绿(构建、静态检查、金丝雀) | 无人 |
| L1 事后告知 | 可逆,影响面中等 | 变更记录 + 观察指标清单 | 次日巡检 |
| L2 事前审批 | 影响面大或跨服务 | 回滚方案 + 观察指标 + 失败判据 | 服务 owner |
| L3 窗口 + 值守 | 不可逆、数据类、容量级 | 演练记录 + 值守人 + 中止条件 | owner + 当晚值班 |
级别不是荣誉等级,它只决定谁来承担判断。L0 的判断由流水线承担(可自动化),L2 的判断由 owner 承担(需要上下文),L3 的判断由在场的两个人共同承担(需要即时决策)。
4. 可逆性是最被低估的维度
| 恢复方式 | 典型耗时量级 | 应属级别 |
|---|---|---|
| 开关切回 / 上一版本镜像回滚 | 秒到分钟 | L0–L1 |
| 重新发布上一版本(含数据兼容) | 十分钟级 | L2 |
| 反向数据迁移 / 手工修数 | 小时级,且可能不可逆 | L3 |
| 依赖外部系统回退(第三方接口、证书) | 不可控 | L3 |
判断规则:能秒级回滚的变更不该走重审批;恢复需要人肉修数据的变更,无论影响面多小都要按最高级处理。
"我们有回滚方案"这句话必须配上一次演练记录。没演练过的回滚方案,在真出事时通常的结局是:发现回滚也需要改数据,于是没人敢按。
5. 审批该看什么
| 审批项 | 该看 | 不该看 |
|---|---|---|
| 变更内容 | 改了什么语义,不只是改了哪个文件 | 代码风格、命名 |
| 失败判据 | 什么现象算失败、多久内判定 | "有问题再说" |
| 观察清单 | 上线后先看哪三个指标、阈值多少 | 全量面板链接 |
| 中止条件 | 满足什么条件立即回滚,不用再讨论 | 依赖审批人现场拍板 |
─── 审批请求的最小内容(占位)
变更: SERVICE_NAME 配置项 TIMEOUT 1s → 3s
失败判据: 5 分钟内 p99 超阈值 或 错误率超阈值 即回滚
观察清单: [p99, error_rate, pool_active]
中止与回滚: 切回上一版本配置(秒级)
承接: ROLE_ONCALL(窗口内在线)
**审批的产出不是"同意",而是"知道要观察什么"。**一个审批人如果签完字答不出"出问题先看哪个指标",这次审批的价值是零——他只是把风险从一个文档搬到了另一个文档。
6. 冻结期、批量变更与它们的代价
| 冻结场景 | 目的 | 副作用 |
|---|---|---|
| 大促、结算日前后 | 避免关键期引入变量 | 解冻首日变更密度骤升,风险反升 |
| 季度末、审计期 | 满足留痕与统计口径 | 变更转入"紧急通道",绕开分级 |
| 长假前后 | 避免无人值守期变更 | 假期前的集中发布成为新高峰 |
冻结期规则(占位):例外必须登记,且有到期日。
freeze:
window: "2026-11-10 ~ 2026-11-13"
allow: [L0]
exception:
require: [ROLE_OWNER, ROLE_ONCALL]
record: "变更单 + 值守人 + 回滚演练时间"
expire: "窗口结束后自动失效"
批量变更要单独定级:依赖升级、配置批量下发、镜像基线更新的共同点是"一次改很多实例",风险不在单点而在分布——一半成功一半失败的状态最难处理。按"受影响实例比例 × 可回滚性"定级,并要求分批(典型做法:先 1 台、再 10%、再全量),每批之间留观察窗。
7. 变更不等于发布
发布只是变更的一种。四类变更的风险点完全不同,用同一套发布检查表必然漏项:
| 变更类型 | 风险点 | 最常漏的检查 |
|---|---|---|
| 代码发布 | 新旧版本共存时的兼容性 | 回滚后旧版本能否读新数据 |
| 配置变更 | 生效范围与生效时机 | 改了但没生效,或只在一部分实例生效 |
| 数据变更 | 不可逆、影响历史数据 | 无备份、无干跑、无影响行数预估 |
| 权限与密钥变更 | 静默失败,故障延后暴露 | 轮换后哪些调用方还在用旧凭证 |
数据变更的最小证据集(占位)
1. 干跑结果:影响行数、命中范围(不是"应该没问题")
2. 备份点:可恢复到的时间戳,且验证过可恢复
3. 执行窗口:低峰 + 值守人在场
4. 中止条件:错误率/延迟超过阈值即停,不等跑完
5. 回滚脚本:与变更脚本同时准备好,且演练过一次
8. 记录来源与"紧急通道"
变更记录必须由流水线产生,不能靠人手填。人手填的记录有两个必然结局:字段被填成"无",或者干脆没人填。流水线能自动带上的字段:提交人、变更内容哈希、目标环境、开始与结束时间、关联工单、回滚版本号。
流水线产出的变更记录(占位):
{
"change_id": "CHG-20261109-014",
"tier": "L2",
"service": "SERVICE_NAME",
"commit": "GIT_SHA",
"window": "2026-11-09T02:00Z/02:40Z",
"rollback_to": "PREV_SHA",
"watch": ["p99_latency", "error_rate", "pool_active"],
"approver": "ROLE_OWNER",
"operator": "ROLE_ONCALL"
}
"紧急变更"通道必须有滥用判据,否则它会成为分级机制的主要入口:
| 信号 | 含义 |
|---|---|
| 事后补单率持续上升 | 分级定得过严,或通道太方便 |
| 同一人反复走紧急 | 个人习惯,还是他的变更总被卡? |
| 紧急变更失败率高于常规 | 说明它被用来绕过观察与演练 |
如果紧急通道的变更失败率明显高于常规变更,问题不在纪律,在分级:该走 L1 的被逼成了"紧急"。
9. 度量:五个能改变决策的数
| 指标 | 口径 | 用来决定什么 |
|---|---|---|
| 变更频次 | 按服务、按级别 | 分级是否把大部分变更放到了 L0/L1 |
| 变更失败率 | 需回滚或需人工介入的比例 | 哪一级的判据失效 |
| 回滚率 | 触发回滚的变更占比 | 可逆性假设是否成立 |
| 审批时长 | 提交到批准,按级别分 | L2 是否在拖慢低风险变更 |
| 冻结期积压 | 解冻后首日的变更条数 | 冻结窗口长度是否合理 |
10. 排错:分级失效的五种现场
| 现象 | 真实成因 | 处理方向 |
|---|---|---|
| 审批三十秒点完 | 表里塞满了 L0 类变更 | 先把可逆且可观测的挪出审批 |
| 高风险变更照样出事 | 分级依据里没有可逆性 | 补可逆性与观测性两个维度 |
| 变更都改到深夜做 | 分级把窗口当成了默认要求 | 只对 L3 要求窗口 |
| 记录字段大量为空 | 靠人手填 | 改为流水线产出 |
| 事故后查不到变更 | 配置变更没进记录 | 配置下发纳入同一记录链路 |
11. 边界:什么时候分级机制的收益低于流程成本
| 场景 | 为什么不该上 | 替代做法 |
|---|---|---|
| 单人团队 | 审批人就是执行人,分级只是自问自答 | 保留变更记录与回滚方案,取消审批环节 |
| 系统无外部用户 | 影响面维度恒为零,分级失去主要依据 | 按可逆性两档:可回滚 / 需备份 |
| 变更总量极低(典型量级:每周个位数) | 分级维护成本高于风险差异 | 全部按 L2 处理,不做四级 |
| 已由外部合规强制规定流程 | 再加一层只会双重记录 | 复用合规证据,不重复审批 |
判断口径:当"分级"带来的审批时长节省,小于维护分级规则与判定争议的成本时,就该退回单一流程 + 强制回滚方案。
12. 自测
- 审批表越来越长、审批越来越快,说明分级机制出了什么问题?
- 为什么"可逆但不可观测"的变更应当和不可逆变更同样对待?
- L0 放行与 L2 审批,本质区别是谁在承担判断?
- "我们有回滚方案"这句话缺了什么才算成立?
- 冻结期结束后第一天的变更密度为什么反而更高?
- 什么规模下,四级模型应该退回成"全部事前审批"?