ADR-0012:指标回滚的信号体系——主警报是"退回旧版事件率",不是崩溃率¶
日期:2026-07-24 状态:已接受
修订关系:细化 ADR-0004 的"指标回滚第一版走人工"——把值班的人看什么定死。
这份记录在讲什么¶
热修推出去之后,值班的人要靠数据判断"这个热修有没有把用户搞坏"。原方案写的是:对比命中与未命中人群的崩溃率和下载成功率。本轮评审发现,把崩溃率当主警报,恰好在最危险的方向上会骗人。这份记录定下三个信号各管什么,以及三条配套小规矩。
为什么崩溃率不能当主警报¶
摔得最惨的人,恰恰喊不出声。
- 小崩(程序闪退):下次打开时会把崩溃报告发出去,我们看得到。
- 大崩(热修把程序搞得根本打不开):永远走不到"发报告"那一步,服务器上一片安静。macOS 的 Crashpad 还是下次成功启动才上传(
Stream/main.cpp:1442)——起不来的机器连上传的机会都没有。
结果是一个荒唐的盲区:热修害人越惨,崩溃率反而越好看。值班的人看着"数据正常",其实一批用户的程序已经打不开了。
而我们手里有个更靠谱的报信人。 防线机制里,程序连崩 3 次会被自动换回旧版(safe 版),换回之后由健康的旧版程序上报"热修 X 把我搞坏了、我已退回"。这条消息必然发得出去(发它的程序是好的)、来得快(崩 2~3 次就触发,分钟到小时级)、意思明确(不是模糊的"有人崩了",而是点名"热修 X 在 brick 机器")。
决定:三个信号各管一种病¶
| 信号 | 管什么 | 打比方 |
|---|---|---|
| 退回旧版/隔离事件率(主警报) | 热修把程序搞得打不开 | 病人自己爬回急诊室说"这药有毒" |
| 崩溃率(辅) | 程序能开,但用着用着闪退 | 吃了药没倒下,但总头晕 |
| 下载成功率 QOS(辅) | 程序好好的,但该修的没修好 | 药吃了,病没好 |
三个警报各管一种失败模式,不指望崩溃率一个指标包打天下——它对最重的病恰恰失灵。
三条配套小规矩¶
一、半夜自动喊人。 灰度是过夜跑的,看板是死的,半夜没人盯。给主警报装个铃:退回旧版事件超过阈值(如 1 小时内 ≥5 台不同机器)→ 飞书自动推送值班人。只喊人、不自动回滚(与 ADR-0004 的"第一版人工决策"一致);CI 侧已有飞书 webhook 管道,成本低。没有这个铃,主警报再快也要等到早上才有人看。
二、崩溃报告打上热修标签。 崩溃率要按热修版本分组才有意义,现在的崩溃上报没有这个字段。做法:启动时把 5 段热修版本号写进崩溃上报的自定义字段(Windows 的 BugTrap / macOS 的 Crashpad)。崩得太早、标签还没打上的极端情况不用管——那种机器起不来,归主警报管,正好各管各的。
三、样本不足就延长观察。 D1 早上如果该站点当晚尝试下载的人太少,成功率没说服力——正确反应是再观察半天,不是硬着头皮拍全量。对 Netflix 级 Tier 0 大站这条基本用不上(一晚的量绰绰有余),写上不吃亏。
这么定之后会怎样¶
- ELK 事件与看板(tech-spec §4.5)以"退回旧版/隔离事件"为第一栏;飞书阈值告警在首次真实热修前必须就绪,属 P0-B2 交付物。
- 崩溃上报的热修版本注解是客户端改造点之一(Windows/macOS 各一处)。
- 北极星目标三与产品规格用户故事 10 的表述同步更新(主信号从"崩溃率对比"改为"退回事件率 + 两辅助")。
- ADR-0011 砍掉维护开关后,命中/未命中两组用户都照常尝试下载,QOS 对比的数据源不再被牌子掐断——两个决定互相成全。