使用方式
这份手册按症状组织,不按章节。线上出问题时,人通常只知道「某个端不对劲」,不知道它属于承诺、能力还是构建问题。先找到最接近的症状,再按「先查什么」的顺序排除。
每条症状分六段:现象、先查什么、常见根因、验证方式、修复动作、预防动作。顺序不能颠倒:先确认事实,再猜原因;先验证修复,再谈预防。
症状一:功能在某个端不可用
现象:同一功能,四个端正常,一个端入口消失或点击无响应。
先查什么:
- 能力快照里这项是
native、polyfill还是absent? - 功能开关在该端是开还是关?
- 实验分组是否排除了该端?
- 客户端版本是否低于最低支持版本?
- 系统权限是否被拒绝?
常见根因:
- 能力探测默认返回「支持」,实际设备不支持。
- 开关按端配置,某个端的配置漏了。
- 旧版本客户端没有新接口,前端直接隐藏入口。
- 权限被拒绝后没有降级路径,只显示空白。
验证方式:让用户提供端、版本、系统版本与功能 id;对照事件日志里的 featureAvailability 五个字段。五项都正常才进入代码排查。
修复动作:按能力策略补降级路径;开关补齐该端配置;旧版本给出升级提示而不是静默隐藏。
预防动作:能力表默认 absent;开关配置纳入发布检查;每个功能至少有一条降级用例。
对应章节:1.3、5.2、3.3。
症状二:同一笔订单在两端状态不同
现象:Web 显示「已支付」,iOS 显示「处理中」,客服无法判断哪一个是真相。
先查什么:
- 两端拿到的是同一份服务端状态,还是各自推导?
- 支付状态与订单状态是否被压进同一个字段?
- 是否有端在本地做了乐观更新且未回滚?
- 缓存是否跨版本复用了旧结构?
常见根因:
- 端上根据支付回调自行推断订单状态。
- 状态字段含义在不同端映射不同。
- 乐观更新失败后没有回滚,界面停留在临时状态。
- 本地缓存没有版本号,旧数据被新代码读取。
验证方式:取同一订单 id,比对服务端原始状态、两端展示状态、两端本地缓存。三者不一致时,以服务端为准,检查端的映射表。
修复动作:状态只由服务端事实驱动;端上映射表集中到共享内核;缓存加 schema 版本。
预防动作:把订单状态纳入 identical 承诺,做跨端契约测试;禁止端上推导支付结果。
对应章节:1.1、1.2、12.2。
症状三:组件样式在各端漂移
现象:同一个按钮,五个端的圆角、间距、字号都略有不同。
先查什么:
- token 是否按三层结构使用,还是各端直接写死值?
- 主题覆盖是否按优先级生效?
- 组件是否被某个端单独 fork 过?
- 设计稿更新后,token 是否同步?
常见根因:
- 组件库有 token,但业务代码绕过组件直接写样式。
- 多品牌覆盖顺序不明确,后加载的覆盖了前一个。
- fork 后的组件没有回流,逐渐分叉。
- token 命名按视觉值而非语义,换主题时失效。
验证方式:抽取同一组件的计算样式,逐端比对 token 解析结果;检查是否存在 fork 目录与深层覆盖。
修复动作:统一 token 解析入口;删除 fork,改为变体参数;主题覆盖按「基础 → 品牌 → 业务」固定顺序。
预防动作:样式检查纳入 CI;组件契约版本化;每季度清理一次 fork。
对应章节:2.1、2.2、2.3。
症状四:发布后白屏或崩溃
现象:新版本在部分设备上启动白屏,或进入某页面即崩溃。
先查什么:
- 崩溃率按端、机型、系统版本如何分布?
- 是否与某个灰度批次强相关?
- 最近是否改动了启动路径或动态配置?
- 是否引入了新的第三方 SDK?
常见根因:
- 动态配置下发了当前版本不认识的字段。
- 插件或热更新包与宿主 API 版本不匹配。
- 新 SDK 初始化阻塞启动,超时后崩溃。
- 降级开关本身依赖了故障服务。
验证方式:按版本与批次切片看崩溃率;回滚最近一次配置或插件;在本地用相同系统版本复现。
修复动作:立即回滚配置/插件;关闭相关灰度;修复后重新走小比例灰度。
预防动作:配置 schema 校验;插件协议版本区间校验;启动路径禁止同步网络调用;灰度观察窗口内不扩大比例。
对应章节:3.1、3.3、5.2、6.3。
症状五:版本迭代后性能持续退化
现象:每个版本首屏慢一点,几个版本后累计多了几百毫秒,但找不到单点。
先查什么:
- 是否有分端、分阶段的预算与基线?
- 退化发生在哪个阶段:网络、解析、渲染还是脚本?
- 是否新增了同步依赖或初始化逻辑?
- 预算超限是否在合并前被拦截?
常见根因:
- 只测总量,没有阶段归因。
- 新增依赖在启动时同步初始化。
- 基线长期不更新,回归比较失效。
- 预算没有 owner,超限无人处理。
验证方式:用同一设备、同一网络、同一版本对比两个构建;按阶段拆分耗时,找出占比增长最大的阶段。
修复动作:把同步初始化改为延迟;拆分大依赖;更新基线并记录变更原因。
预防动作:预算进入 CI;每次合并比较阶段耗时;每月复核一次基线。
对应章节:4.1、4.2、4.3。
症状六:线上问题无法定位
现象:用户反馈「用不了」,但日志里找不到对应记录,或记录字段不全。
先查什么:
- 事件是否满足最小字段契约?
- 错误与阻塞事件是否被采样?
- 是否有 trace id 串联前后端?
- 告警是否有 owner 与 runbook?
常见根因:
- 字段命名不统一,无法按功能聚合。
- 采样率对所有事件一致,错误被大量丢弃。
- 日志在采集端未脱敏,敏感字段被整体关闭。
- 告警只发群,无明确处理人。
验证方式:用用户提供的端、版本、时间窗检索;检查该事件是否命中采样;检查 trace 是否可跨端关联。
修复动作:补齐必填字段;错误与阻塞改为全量;按功能建立查询视图。
预防动作:事件契约纳入评审;采样策略按等级;每条告警绑定 owner 与 runbook。
对应章节:7.1、7.2、7.3。
症状七:第三方 SDK 带来隐私风险
现象:合规扫描发现某 SDK 采集了未声明的数据,或初始化早于用户同意。
先查什么:
- SDK 是否在清单中,版本与权限是否登记?
- 初始化时机是否在同意之后?
- 采集字段是否超出功能所需?
- 是否有退出与替换方案?
常见根因:
- 业务直接接入 SDK,未经过平台团队。
- SDK 在 Application 启动时自动初始化。
- 权限申请与功能使用时机脱节。
- 清单长期未更新,已下线 SDK 仍在采集。
验证方式:抓包与静态扫描结合;核对同意记录时间与 SDK 初始化时间;比对清单与实际依赖。
修复动作:延迟初始化到同意之后;关闭非必要采集;下线无主 SDK。
预防动作:SDK 接入走白名单;初始化统一收口;每季度复核清单。
对应章节:8.1、8.2、8.3。
症状八:区域格式错误
现象:中东用户看到金额小数位错误,或美洲用户看到日期差一天。
先查什么:
- 金额是否用整数最小单位存储与计算?
- 时区是否统一存 UTC、按区域展示?
- 小数位与舍入规则是否按币种配置?
- 日期格式是否依赖系统 locale?
常见根因:
- 用浮点数存金额,累加后出现分级误差。
- 展示时直接取本地时间,未做时区转换。
- 所有币种统一两位小数,忽略了零小数位币种。
- 文案拼接导致语序与复数错误。
验证方式:构造边界金额与跨时区时间,逐区域跑格式化测试;比对服务端与端上展示。
修复动作:金额改整数;时间统一 UTC;按币种配置小数位与舍入;文案改用带参数的模板。
预防动作:格式化纳入共享内核;每个区域至少一条回归用例。
对应章节:9.1、9.2、9.3。
症状九:读屏用户无法完成操作
现象:视障用户反馈按钮读不出、焦点跳走、状态变化无播报。
先查什么:
- 控件是否有角色、名称与状态?
- 焦点顺序是否与视觉顺序一致?
- 状态变化是否有播报?
- 是否只靠颜色传达信息?
常见根因:
- 用不可聚焦的容器模拟按钮。
- 自定义弹窗没有焦点陷阱与恢复。
- 异步加载后焦点丢失。
- 错误提示只变红,没有文本。
验证方式:开启读屏走一遍主流程;检查焦点顺序;用高对比与放大字体复测。
修复动作:改用语义控件;补名称与状态;修复焦点管理;错误提示加文本。
预防动作:无障碍检查进入组件契约;主流程每版本人工走查一次。
对应章节:10.1、10.2、10.3。
症状十:迁移长期卡在中途
现象:新旧两套架构并存一年多,新路径流量上不去,旧路径没人敢删。
先查什么:
- 迁移是否有明确的退出条件?
- 双写是否有一致性校验?
- 卡住的原因是技术、数据还是组织?
- 旧路径是否还有独占功能?
常见根因:
- 只定义了开始,没有定义结束。
- 双写长期不一致,团队不敢切流量。
- 旧路径仍有未迁移的边界功能。
- 没有 owner 推动收尾。
验证方式:统计新旧路径流量、差异率、未迁移功能清单;访谈相关负责人确认阻塞点。
修复动作:补齐退出条件;先修数据差异;拆分剩余功能;指定收尾 owner 与截止时间。
预防动作:迁移启动时同时写退出条件;每两周复核差异率;设置「无流量观察期」后再删除。
对应章节:12.1、12.2、12.3。
排查的通用顺序
十类症状背后有一条共同顺序:
- 确认事实:哪个端、哪个版本、哪个用户、什么时间。
- 定位层:能力、开关、契约、构建、运行时,逐层排除。
- 比对基线:与上一个正常版本、另一个正常端比较。
- 验证修复:在相同条件下复现并确认消失。
- 补预防:把这次排查变成一个检查项或一条用例。
跳过前三步直接改代码,通常会修错地方;跳过第五步,同一个问题会以另一种形式回来。
一页纸速查
| 症状 | 第一问 | 最可能的层 |
|---|---|---|
| 功能不可用 | 能力快照是什么? | 能力/开关 |
| 状态不一致 | 谁推导了状态? | 承诺/契约 |
| 样式漂移 | 是否绕过 token? | 设计系统 |
| 白屏崩溃 | 最近改了什么配置? | 插件/配置 |
| 性能退化 | 哪个阶段变慢? | 预算/归因 |
| 无法定位 | 字段齐吗?被采样了吗? | 可观测性 |
| 隐私风险 | SDK 何时初始化? | 安全/合规 |
| 格式错误 | 金额怎么存?时区怎么转? | 国际化 |
| 读屏不可用 | 控件有角色吗? | 无障碍 |
| 迁移卡住 | 退出条件是什么? | 治理/迁移 |
速查表不能替代排查,但能让你从正确的层开始。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。