Android稳定性-48-Top Issue 怎么管理:从问题列表到版本风险收敛

做 Top Issue 管理,最怕把它理解成“高优先级缺陷列表”。如果只是把 P0、P1 缺陷复制到一个表格里,再每天问一遍 owner 有没有进展,这个列表很快会失去价值:问题数量越来越多,状态越来越像口头承诺,版本会议上每个人都能说出风险,却没有人能回答版本还能不能继续推进。

真正有效的 Top Issue 管理,是把稳定性问题放进版本节奏里做风险收敛。它既不是测试团队单独维护的日报附件,也不是研发团队用来解释延期的材料,而是一个共同认可的决策台账:哪些问题阻断发布,哪些问题必须在下一轮验证前有结论,哪些问题可以带条件灰度,哪些问题需要转成平台能力或长期专项。

这篇只讨论 Android 稳定性版本里的 Top Issue。Crash、ANR、Watchdog、system_server 卡死、随机重启、黑屏、温升、功耗、低存储卡顿、相机打开失败、蓝牙断连、OTA 失败,都可能进入 Top Issue;但不是所有异常都应该进入。进入的标准不是“看起来严重”,而是它对版本目标、用户路径、复现概率、诊断能力和修复窗口产生了明确影响。

一、Top Issue 不是缺陷池,而是版本风险池

缺陷池关心的是单个 bug 的生命周期:创建、分派、修复、验证、关闭。Top Issue 关心的是版本风险是否下降:同类问题是否被聚合,阻断路径是否清晰,剩余风险是否有人接受,验证样本是否足够支撑结论。

举个简单例子。某个版本里有三个缺陷:相机冷启动偶发黑屏、视频通话切后台后画面冻结、扫码应用连续打开相机失败。从缺陷系统看,它们可能属于三个应用、三个 owner、三个复现路径;从 Top Issue 视角看,它们可能都是 CameraService 到 vendor camera provider 的会话回收问题。此时继续按三个缺陷分别推进,会议上会得到三个“还在分析”;把它们归并为一个 Top Issue,才可能统一拉起相机、Framework、HAL、测试和版本 owner,判断版本是否需要暂停准入。

Top Issue 的粒度通常介于“单个缺陷”和“专项风险”之间。粒度太小,会变成缺陷列表;粒度太大,会变成一句空泛的“稳定性不达标”。比较合适的表达是:一个可命名的风险对象,能够绑定现象边界、影响范围、责任链路、当前证据、下一步动作和关闭条件。

对象 管理重点 常见问题 适合的输出
普通缺陷 单点修复闭环 状态同步不及时 缺陷单、验证记录
Top Issue 版本风险收敛 边界不清、证据不足 风险台账、日推进结论
专项治理 长期能力建设 目标过大、周期过长 专项计划、平台规则
准入阻断项 发布决策 口径争议 准入评审结论

Top Issue 管理的第一条原则是:它必须能影响资源调度或版本判断。如果一个问题进入列表后,没有更高频的跟踪、没有更清楚的 owner、没有更强的验证要求,也不会改变发布策略,那它不该叫 Top Issue。

二、进入 Top Issue 的判定口径

版本后期的问题很多,不能靠嗓门决定谁进入 Top Issue。建议把入口标准写清楚,并在每个版本启动时同步给测试、研发、项目和质量团队。

一个问题满足下面任意一类,就应该评估是否进入 Top Issue。第一类是用户影响大,例如开机、解锁、通话、相机、支付、导航、蓝牙车机、系统升级这类高频或高价值路径出现稳定性异常。第二类是系统层级高,例如 system_server ANR、Watchdog、SurfaceFlinger 异常、kernel panic、vendor service 死亡、binder 线程池耗尽。第三类是趋势异常,例如同一版本相同模块 Crash 率突然上升,或者长稳测试在多个设备上出现同类重启。第四类是诊断困难,例如只出现一次但后果严重,日志不完整,复现路径不稳定,短期无法证明风险已经消除。

也要明确不应进入的情况。测试脚本误操作、环境网络中断、单台老化设备硬件故障、已知外部服务异常,如果没有证据指向版本代码或系统配置变化,先进入普通异常池,而不是直接升级为 Top Issue。这样做不是降低关注,而是避免列表被噪声淹没。

一个可执行的准入判断可以写成四问:

  • 这个问题是否影响版本主路径或核心体验。
  • 这个问题是否可能在用户规模扩大后放大。
  • 这个问题是否需要跨团队资源才能推进。
  • 这个问题是否有明确的关闭条件和验证方案。

如果四问中至少两项为是,基本就值得进入 Top Issue 评审;如果全部为否,继续按普通缺陷管理即可。

三、Top Issue 台账字段应该少而硬

Top Issue 表最常见的失败方式,是字段很多但每个字段都很软。比如“风险描述”“当前进展”“下一步计划”写满了长句,却看不出今天和昨天有什么不同,也看不出谁负责把风险降下来。

建议字段不要追求多,而要保证每一列都能被检查。

字段 写法要求 不合格示例 合格示例
Issue 名称 现象 + 场景 + 模块 相机问题 冷启动相机 2/80 黑屏,疑似 provider 会话回收超时
影响范围 版本、设备、路径、概率 部分机型 V1.2.7,A02/A03,冷启动相机,2.5%
风险等级 阻断、观察、可带条件 阻断准入,因命中主路径且无规避方案
当前证据 可复查日志、截图、时间点 有日志 bugreport-0421-1430,event log 14:29:51 provider died
Owner 能推动闭环的人 相机组 camera HAL owner:张三;Framework 协同:李四
下一动作 到时间点的具体动作 继续分析 4 月 22 日 18:00 前给出 provider 超时原因或排除结论
关闭条件 验证样本和判定门槛 复测通过 修复包 3 轮,每轮 20 台 x 24h,无同类黑屏且日志无 timeout

台账的核心不是格式漂亮,而是让会议可以逐项追问:证据有没有变,风险有没有下降,动作有没有完成,关闭条件有没有满足。只要这四件事清楚,表格可以很简洁。

四、分级要绑定版本动作

Top Issue 分级不能只写 S、A、B,也不能只写 P0、P1。等级必须对应版本动作,否则等级没有管理意义。

建议把等级定义成四档。

等级 含义 版本动作 示例
Blocker 当前版本不得准入或发布 暂停准入、停止灰度、必须修复验证 随机重启、system_server Watchdog、开机失败
Critical 不一定立即停版,但必须日清进展 升级 owner,每日评审,修复窗口锁定 主路径 ANR、相机黑屏、OTA 后设置丢失
Watch 可继续测试,但必须观察趋势 灰度门槛收紧,增加采样 低概率功耗异常、单路径偶发卡顿
Follow 对当前发布影响有限 转普通缺陷或后续专项 非主路径低概率 UI 异常

分级要允许升降级。一个 Watch 问题,如果在新包里复现概率升高,或者发现影响范围扩大,就要升为 Critical;一个 Blocker 问题,如果修复方案明确、验证样本足够、线上规避可用,可以降为 Watch 并进入灰度观察。分级不是给问题贴标签,而是随证据变化调整版本动作。

五、完整案例:相机冷启动黑屏如何从散点缺陷变成 Top Issue

下面用一个完整案例说明 Top Issue 的推进方式。

版本 V3.8.12 进入稳定性准入阶段后,测试团队在 60 台设备上跑 48 小时业务遍历。第一个晚上出现两条缺陷:一台设备冷启动相机后预览黑屏,另一台设备在扫码应用调用相机时卡住。第二天上午,Monkey 组又发现一次 Camera App 无响应。三个缺陷最初分散在不同项目里,owner 也不同。

如果只看单个缺陷,每个问题都很难下结论:概率低,复现慢,日志量大,App 表现也不完全一致。但测试 owner 把三个缺陷的时间线放在一起后,发现异常前后都出现了 camera provider not respondingCameraService: disconnect timeout、SurfaceFlinger 没有新的 buffer 提交。于是把三个缺陷归并为 Top Issue:V3.8.12 冷启动相机链路偶发黑屏,疑似 provider 会话释放超时

当天的 Top Issue 记录不是写“相机组继续分析”,而是写成这样:

1
2
3
4
5
6
7
Issue: V3.8.12 冷启动相机链路偶发黑屏
等级: Blocker
影响: A03/A04,两类相机入口,3/1800 次,命中相机主路径
证据: run_0421_cam_07,14:29:51 CameraService disconnect timeout;14:29:52 provider 无响应;14:29:54 App 等待首帧
Owner: camera HAL owner 张三;Framework camera owner 李四;测试 owner 王五
下一动作: 4 月 22 日 12:00 前确认 provider 线程是否卡在 close session;18:00 前给出临时规避或修复包
关闭条件: 修复包在 A03/A04 各 20 台,冷启动、扫码、视频通话三类入口累计 3000 次无黑屏;日志中无 disconnect timeout

研发分析后发现,V3.8.12 合入了一个低功耗切换补丁,某些情况下 camera provider 在释放上一轮 session 时等待 sensor power down 完成,而 App 新会话已经开始申请,导致 close 和 open 在 vendor 层串行等待。修复方案不是改 App,也不是延长等待时间,而是在 provider 中调整 close session 的状态机,避免持有全局锁等待电源回调。

修复包出来后,测试没有只跑最初的 Camera App,而是补了三类入口:系统相机冷启动、扫码应用快速开关、视频通话预览切换。验证通过后,Top Issue 降级为 Watch,在灰度前 24 小时继续观察相机异常率。最终关闭时,台账里保留了缺陷关联、修复 commit、验证样本和后续监控规则。

这个案例的关键不是相机问题本身,而是三个动作:先聚合相似现象,再用证据定义风险边界,最后用验证样本证明风险下降。

六、常用命令:证据提取要服务于台账

Top Issue 推进中,命令不是越多越好。每条命令都应该回答一个问题:异常发生在什么时候、涉及哪些进程、系统资源是否异常、同类问题是否重复出现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 保留全缓冲日志,适合 Top Issue 归档
adb logcat -b all -v threadtime -d > logcat_all.txt

# 导出 bugreport,保留系统服务状态和历史异常
adb bugreport bugreport_top_issue.zip

# 查看近期 dropbox 记录,确认 crash/anr/watchdog 是否存在
adb shell dumpsys dropbox --print | head -n 200

# 查看关键进程状态
adb shell ps -A | grep -E 'system_server|surfaceflinger|camera|media|vendor'

# 查看 binder 状态,排查线程池耗尽或调用阻塞
adb shell cat /sys/kernel/debug/binder/state > binder_state.txt

# 查看重启原因
adb shell getprop ro.boot.bootreason
adb shell cat /sys/fs/pstore/console-ramoops-0 2>/dev/null

/sys/kernel/debug/binder/sys/fs/pstore 通常依赖 userdebug/eng、root 或厂商工程权限。user 版本无法读取时,要把缺失原因写进证据栏,并使用 bugreport、dropbox、traces、厂商日志或复现工程包补齐,而不是把命令失败解释成“无异常”。

如果是批量设备,可以用一个轻量脚本把证据目录固定下来:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env bash
set -euo pipefail
serial="$1"
issue="$2"
out="evidence/${issue}/${serial}_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$out"
adb -s "$serial" get-state > "$out/device_state.txt"
adb -s "$serial" shell getprop ro.build.fingerprint > "$out/fingerprint.txt"
adb -s "$serial" logcat -b all -v threadtime -d > "$out/logcat_all.txt"
adb -s "$serial" bugreport "$out/bugreport.zip"
adb -s "$serial" shell dumpsys dropbox --print > "$out/dropbox.txt" || true

这类脚本的价值,是让每个 Top Issue 的证据结构一致。到了评审会,不需要重新问“日志在哪、版本号是什么、设备号是什么”。

七、推进节奏:日会只解决四个问题

Top Issue 日会不应该变成所有人轮流汇报。稳定性版本后期时间很贵,每个 issue 只需要回答四个问题。

第一,昨天到今天新增了什么证据。没有新增证据,就说明问题没有实质推进。第二,风险等级是否变化。复现概率、影响范围、修复状态、验证结果都可能改变等级。第三,下一步动作是否足够具体。动作必须有 owner、时间点和产出。第四,是否需要版本决策。比如是否暂停冒烟、是否切换基线、是否增加灰度门槛、是否允许带风险进入下一阶段。

一个 30 分钟的 Top Issue 会,宁可只讲 5 个真正阻断的问题,也不要把 40 个缺陷都念一遍。会议结束后,台账至少要更新三类信息:状态变化、责任动作、版本判断。没有这三类更新,会议就只是同步。

八、风险趋势比单日状态更重要

Top Issue 管理容易被当天状态带偏。某个问题今天没有复现,不代表风险消失;某个问题今天新增一次,也不一定说明版本不可用。要看趋势。

建议给每个 Top Issue 建一条简单趋势线:发现时间、复现次数、影响设备数、修复包、验证轮次、灰度数据。这样能避免两种误判:第一种是“今天没复现,所以关闭”;第二种是“今天又复现,所以所有结论推翻”。

日期 包版本 设备数 场景次数 复现次数 动作 判断
4/21 V3.8.12 60 1800 3 建立 Top Issue Blocker
4/22 V3.8.13-fix1 20 900 1 修复不完整 Blocker
4/23 V3.8.14-fix2 40 2400 0 扩大验证 Critical
4/24 V3.8.14 80 5000 0 灰度观察 Watch

趋势表不需要复杂,但要能解释为什么风险下降。仅写“验证通过”说服力不够;写清设备数、场景次数、复现次数和包版本,版本 owner 才能做判断。

九、常见误判

Top Issue 管理中有几类误判非常常见。

第一,把概率低等同于风险低。系统重启、数据丢失、开机失败、OTA 失败,即使只出现一次,也可能是发布阻断项。概率要和后果一起看。

第二,把 owner 明确等同于风险收敛。有人负责只是开始,不代表问题有结论。Top Issue 要看证据、修复和验证,不看口头承诺。

第三,把修复合入等同于关闭。稳定性问题尤其不能这样处理。修复包必须经过目标场景验证,必要时还要覆盖相邻场景和压力场景。

第四,把单设备异常直接排除。设备硬件问题确实存在,但排除前要看同批次、同版本、同场景是否有相似信号。过早归因硬件,会漏掉低概率系统问题。

第五,把日志多等同于证据充分。证据充分的标志不是文件数量,而是能还原时间线,能解释根因假设,能支撑版本动作。

十、检查清单

在每次 Top Issue 评审前,可以用下面清单快速扫一遍。

  • Issue 名称是否能看出场景、现象和疑似链路。
  • 是否写明影响版本、设备范围、复现概率和用户路径。
  • 是否有可复查证据,包括日志路径、时间点、截图或录屏。
  • 是否明确当前等级,以及等级对应的版本动作。
  • 是否有唯一主 owner 和必要协同 owner。
  • 下一步动作是否带时间点和可交付结果。
  • 关闭条件是否包含样本量、场景、版本和判定标准。
  • 修复后是否安排回归、相邻场景验证和趋势观察。
  • 是否需要同步到版本准入、日报、灰度策略或案例库。
  • 是否存在长期治理项,避免同类问题反复出现。

这份清单适合放在评审会前,也适合测试 owner 每天更新台账前自查。

十一、输出物模板

下面是一份可以直接使用的 Top Issue 输出模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Top Issue:<场景 + 现象 + 疑似链路>

## 1. 基本信息
- 版本:<build fingerprint / build id>
- 发现阶段:<准入长稳 / 专项 / 灰度 / 线上>
- 影响设备:<型号 / 批次 / 数量>
- 风险等级:<Blocker / Critical / Watch / Follow>
- 主 owner:<姓名 / 团队>
- 协同 owner:<姓名 / 团队>

## 2. 现象和影响
- 用户路径:<用户会怎样触发>
- 表现:<黑屏 / ANR / 重启 / 卡死 / 功耗异常>
- 概率:<复现次数 / 总次数 / 设备数>
- 后果:<是否影响发布、灰度、售后或主路径>

## 3. 证据
- 时间点:<yyyy-mm-dd hh:mm:ss>
- 日志路径:<bugreport / logcat / traces / pstore>
- 关键片段:<只贴最能说明问题的几行>
- 关联缺陷:<bug id 列表>

## 4. 当前判断
- 疑似模块:<Framework / Native / HAL / Kernel / App>
- 已排除项:<环境 / 脚本 / 单设备硬件等>
- 待确认项:<下一步需要证明或排除什么>

## 5. 推进计划
| 动作 | Owner | 截止时间 | 输出 |
| --- | --- | --- | --- |
| <动作> | <owner> | <time> | <结论或文件> |

## 6. 关闭条件
- 修复版本:<build id>
- 验证场景:<场景列表>
- 样本量:<设备数 x 时长 / 次数>
- 通过门槛:<无复现 / 指标回到基线 / 无同类日志>

## 7. 关闭结论
- 最终根因:<一句话说明>
- 修复方式:<commit / 配置 / 回滚 / 规避>
- 遗留风险:<无 / 有,如何观察>
- 沉淀动作:<案例库 / 门禁 / 脚本 / 监控>

模板的重点是让每个字段都能被审阅。不要把它写成周报,也不要把它写成缺陷单复制件。

十二、和版本准入、量产验收的关系

Top Issue 是版本准入的输入,不是准入结论本身。准入评审要看全部指标、阻断项、灰度策略和遗留风险;Top Issue 提供其中最需要决策的风险对象。

到了量产前,Top Issue 台账还会变成遗留问题评审材料。哪些问题已经关闭,哪些问题带条件放行,哪些问题需要售后监控,哪些问题必须写进版本发布说明,都要从这个台账里追溯。如果前期记录不清,量产评审会就只能靠记忆判断,风险很高。

因此,Top Issue 每次关闭时都应该问一句:这个问题是否需要进入案例库、准入规则或自动化监控。如果答案是需要,却没有人承接,那么同类问题很可能在下个版本重新出现。

十三、把 Top Issue 变成自动化信号

人工台账只能解决责任和决策问题,不能替代自动发现。成熟一些的团队,会把高频 Top Issue 的识别规则沉淀到日志平台或测试平台里。比如相机黑屏问题关闭后,不应该只保留一篇复盘,还应该增加 CameraService disconnect timeout、provider 死亡、首帧超时、SurfaceFlinger 无 buffer 更新这些检测规则。下一次长稳中只要出现相似组合,平台就能自动打上疑似标签,并推送给测试 owner。

自动化信号不一定一开始就很复杂。可以先从关键字和时间窗口做起:在同一设备、同一测试 run、同一 5 分钟窗口内,如果同时出现 App 等待首帧、CameraService timeout、provider warning,就生成一条疑似相机链路异常。后续再逐步加入进程状态、dumpsys 输出和历史基线。这样做的好处,是 Top Issue 不再完全依赖某个人的经验敏感度。

Top Issue 类型 可自动化信号 平台动作
Watchdog dropbox watchdog、system_server 栈、bootreason 自动升级为阻断候选
相机黑屏 CameraService timeout、provider error、首帧超时 关联相机专项和历史案例
随机重启 pstore、bootreason、kernel panic 关键字 触发重启分析模板
低存储卡顿 df 低余量、I/O wait、vold/installd 阻塞 增加低存储专项复测
功耗异常 wakelock 持续、后台进程异常、温度升高 推送功耗 owner 复核

自动化规则要保留人工确认入口。平台给出的只是疑似风险,不应该直接替代版本判断。它真正解决的是发现速度和证据聚合,让测试 owner 在日会前就拿到候选问题和日志索引。

十四、不同版本阶段的管理差异

同一个 Top Issue,在版本早期、中期、后期和灰度阶段的处理方式不同。早期更关注根因方向,中期更关注修复收敛,后期更关注验证充分性,灰度阶段更关注止损能力。如果不区分阶段,团队容易在早期过度讨论发布结论,或者在后期还停留在“继续分析”。

版本早期发现的 Top Issue,允许根因假设有不确定性,但必须尽快明确影响范围和复现路径。版本中期要关注修复方案是否进入主线,以及是否有足够时间做回归。版本后期要减少探索性动作,重点检查关闭条件是否满足。灰度阶段则要把实验室证据和线上指标连起来看,任何新信号都要判断是否触发暂停或回滚。

1
2
3
4
早期:定义边界 -> 聚合缺陷 -> 找主 owner -> 建复现和证据路径
中期:确认根因 -> 锁定修复方案 -> 建验证计划 -> 跟踪趋势
后期:检查关闭条件 -> 评估遗留风险 -> 形成准入建议
灰度:监控线上指标 -> 判断放大趋势 -> 执行暂停或回滚策略

阶段差异还会影响会议频率。早期可以隔天更新,中后期的 Blocker 需要每日更新,灰度阶段的高危 Watch 项可能需要按小时观察。Top Issue 管理要跟版本节奏同步,不能一套频率从头用到尾。

十五、Top Issue 关闭后的复用动作

关闭不是终点。一个真正有价值的 Top Issue,关闭后至少应该产生一个复用动作。可能是新增自动化用例,可能是准入规则,可能是案例库条目,可能是日志平台告警,也可能是代码评审检查项。

建议在关闭结论里增加“复用动作”字段,并在下一次版本回顾时检查是否落实。比如相机黑屏问题关闭后,复用动作可以是:相机专项增加快速开关和多入口首帧检查;日志平台增加 provider timeout 规则;版本准入中新增相机打开失败率门槛;案例库新增 camera first frame 条目。如果这些动作没有落地,问题虽然关闭了,团队能力没有提升。

复用动作要小而明确。不要写“加强相机稳定性测试”,这种话无法验收。应该写“在 camera_smoke.py 中增加扫码入口连续打开 500 次,记录 first_frame_ms 和 provider timeout,门槛为失败率 0”。这样的动作才能真正进入工程体系。

十六、小结

Top Issue 管理的目标,不是把严重问题摆出来给大家看,而是让版本风险一天天变小。有效的 Top Issue 台账要能回答六件事:问题影响什么,证据在哪里,谁负责推进,下一步交付什么,什么时候能判断,满足什么条件才能关闭。

如果一个问题已经进入 Top Issue,就不要再用普通缺陷的节奏处理它。它需要更清楚的边界、更硬的证据、更短的反馈周期和更明确的版本动作。做到这些,Top Issue 才能从“问题列表”变成真正的风险收敛工具。