APM 与线上监控
☆ APM 是把“性能优化“从本地经验升级成线上体系的关键。你的风控 SDK 背景可以重点讲 native crash、采样、灰度和宿主影响控制。
一、APM 监控什么
| 类型 | 指标 | 关键证据 |
|---|---|---|
| Crash | Java crash、native crash、崩溃率 | 堆栈、版本、机型、ABI |
| ANR | 主线程阻塞、输入超时、广播/Service 超时 | traces、主线程栈、锁等待 |
| 卡顿 | 慢帧、冻结帧、帧率 | Choreographer/FrameMetrics/Perfetto |
| 启动 | 冷启动、首帧、可交互时间 | launch trace、业务埋点 |
| 网络 | 成功率、耗时、错误码、弱网 | interceptor、DNS/TLS/connect/read 分段 |
二、Crash 监控:Java 与 Native
Java crash 常通过 Thread.setDefaultUncaughtExceptionHandler 捕获;native crash 需要 signal handler 或 Breakpad/Crashpad 这类方案。
面试边界:不要说“所有 native crash 都能优雅恢复“。多数情况下只能采集现场、下次启动上报、灰度回滚。
三、ANR 与卡顿监控
- ANR:系统判定,重点是拿到 traces 和主线程阻塞证据。
- 卡顿:应用侧可用主线程 watchdog、Choreographer 帧回调、FrameMetrics 监控。
- 线上采样必须控制开销,避免监控本身制造卡顿。
四、启动与网络监控
启动监控要区分进程创建、Application、首 Activity、首帧、业务首页可交互。网络监控要拆 DNS、TCP、TLS、请求、响应、解析,不要只报一个总耗时。
五、上报链路、采样与隐私
- 本地缓存:避免 crash 当场丢失日志。
- 批量上报:减少电量和流量开销。
- 采样:高频事件不能全量。
- 隐私:不上传明文 token、手机号、身份证、设备敏感字段。
六、怎么把 SDK 经历讲成亮点
可以这样组织:“SDK 嵌入宿主 App 后,我关注的不只是功能成功,还要保证不拖累宿主稳定性。我们会监控 native crash、初始化耗时、线程/网络开销,灰度阶段看指标,异常时能按版本/ABI/机型聚合定位。”
七、线上定位闭环:符号化、聚类、告警与回归检测
APM 面试的加分点是讲清“采集之后怎么用”。只说捕获 crash 不够,还要能把问题聚类、定位、告警、灰度拦截。
Crash 符号化流水线
| 环节 | 关键数据 | 作用 |
|---|---|---|
| 构建归档 | versionCode、git sha、mapping、native symbols、build id | 确保线上堆栈能还原 |
| 崩溃采集 | Java stack、signal、寄存器、线程栈、ABI、机型 | 保留现场 |
| 符号化 | R8 mapping、so debug symbols | 还原混淆方法和 native 函数 |
| 聚类 | 崩溃栈 fingerprint、版本、设备维度 | 找 Top N 问题而不是看单条日志 |
Native crash 尤其要强调 build id/符号文件匹配。没有对应版本的 symbols,即使采集到了 tombstone 也很难定位。
ANR 与卡顿聚类
- ANR 不只看主线程栈,还要看锁等待、Binder 调用、IO、CPU 占用和发生场景。
- 卡顿指标要用慢帧/冻结帧比例、P90/P99,不要只报平均 FPS。
- traces 需要按主线程栈 fingerprint 聚类,否则线上会被大量重复样本淹没。
Dashboard 与告警
| 指标 | 常用维度 | 典型用途 |
|---|---|---|
| crash-free users/sessions | 版本、渠道、系统、机型、ABI | 判断能否继续灰度 |
| ANR 率 | 页面、进程、系统版本 | 发现主线程/厂商 ROM 问题 |
| 启动 P50/P90/P99 | 冷/温/热启动、渠道、机型档位 | 识别长尾体验 |
| 网络成功率/耗时 | 域名、接口、地区、网络类型 | 区分端侧和服务端问题 |
告警不要只设固定阈值,还要看环比/同比和灰度版本对照。小流量灰度时,一个新增 Top crash 比整体 crash 率更敏感。
Breadcrumb 与隐私脱敏
客户端可维护轻量环形日志,记录页面跳转、关键按钮、网络错误、配置版本等 breadcrumb。注意只记录定位所需上下文,不要写入 token、手机号、身份证、精确位置等敏感数据。
APM SDK 自身开销
APM SDK 也要被监控:初始化耗时、线程数、磁盘占用、上报流量、采样命中率、丢弃原因。面试可以说“监控系统本身不能成为性能问题”。
高频面试题
Q1:线上卡顿怎么监控? 答:轻量方案是主线程 watchdog 或 Choreographer 统计慢帧;深入定位要结合 Perfetto/trace。线上只采样关键指标,本地复现再做完整 trace。
Q2:native crash 怎么定位? 答:采集 signal、寄存器、线程栈、so build id/版本/ABI,结合未 strip 符号或 symbol server 还原堆栈,按版本和机型聚类。
Q3:APM SDK 会不会影响性能? 答:会,所以要采样、异步、批量、延迟上报,关键路径不做重 IO,监控逻辑本身也要被监控。
Q4:线上 crash 很多时怎么快速定位优先级? 答:先按版本、机型、ABI、系统和堆栈 fingerprint 聚类,看新增问题、影响用户数、是否阻断核心路径。Java crash 用 mapping 还原,native crash 用 build id 匹配 symbols。灰度期如果出现新增 Top crash,应暂停放量并用配置降级或热修复处理。
Q5:为什么性能指标要看 P90/P99 而不只看平均值? 答:平均值会掩盖长尾问题。移动端用户体验常被低端机、弱网、特定 ROM 拉垮,所以启动、卡顿、网络耗时都要看分位数和维度拆分。
易错点 / 追问
- 不要把本地 Profiler 等同于线上 APM。
- 不要上传敏感业务数据。
- 不要只讲采集,还要讲聚合、告警、灰度回滚和修复闭环。