← 全部材料 排查
DEBUGGING · 12 个排查场景

会排查的人先缩范围

排查能力的差别不在工具熟不熟,而在会不会把搜索空间砍半:先定性、再二分、一次只验证一个假设。这份按症状组织,每种症状给出最短的定位路径。

01先定性再动手必现还是偶现、影响面、时间点,四个问题能砍掉大半范围。
02按症状找入口白屏看 Network、慢看 Performance、CPU 高看火焰图,别混着来。
03止血优先线上故障先恢复服务,根因可以事后慢慢查。
1

排查的第一步是定性★

把搜索空间砍成一半
不要一上来就翻代码。先回答四个问题:必现还是偶现、影响面多大、什么时候开始的、最近改了什么。这四个答案会把范围从"整个系统"缩到"某次发布里的某个改动"。
◐ 可交互:给一个现象,走一遍真实的分叉
现象白屏、报错、变慢、数据不对——具体是哪一种
→
范围全量还是部分用户、什么端、什么网络
→
时间点什么时候开始,和哪次发布/配置变更重合
→
假设提出一到两个可验证的猜测
→
验证用日志、指标、复现去证实或推翻
面试怎么答我会先问四个问题:必现还是偶现、影响面多大、什么时候开始的、最近改了什么。必现基本是代码或配置问题,偶现多半是并发和缓存。然后把故障时间和发布记录对齐,通常能直接锁定是哪次改动。之后一次只验证一个假设,避免混淆因果。
2

白屏与 JS 报错★

先分清是没拿到 HTML,还是拿到了但没渲染
白屏分两层:资源层(HTML 没回来、JS 404、CDN 返回错版本)和执行层(JS 报错、依赖缺失、渲染前抛异常)。判断方法很简单:看 Network 面板里主文档和主 JS 的状态码,再看 Console 有没有红字。

资源层的问题

  • HTML 200 但是空壳:后端模板渲染失败
  • JS 404:发版后旧 HTML 引用了已删除的 chunk
  • JS 200 但内容是 HTML:CDN 把 404 换成了首页
  • 证书过期:整个域名加载失败

执行层的问题

  • SyntaxError:语法不被目标浏览器支持
  • Cannot read property of undefined:数据没到就渲染
  • ChunkLoadError:动态 import 的文件找不到
  • 循环依赖导致某模块是 undefined
面试怎么答白屏先分两层看:资源层看 Network,主文档和主 JS 的状态码、返回内容对不对;执行层看 Console 的报错。最常见的两个原因是发版后旧页面请求旧 hash 的 chunk 得到 404,以及服务器把 404 回落成了 index.html 导致 JS 拿到 HTML。
3

性能问题:从现象到指标★

先确定慢在哪一段
"页面慢"要先拆成三段:网络(请求多久回来)、渲染(解析和绘制多久)、交互(点了多久有反应)。三段对应完全不同的优化手段,混在一起讨论就会变成互相猜。
三段各看什么网络 DevTools Network 的瀑布图 / 首字节时间 TTFB 关注:请求数、串行依赖、体积、CDN 命中率 渲染 Performance 面板 / LCP、CLS 关注:主线程长任务、阻塞渲染的资源、布局抖动 交互 INP(取代了 FID) 关注:事件回调耗时、是否触发了大量重渲染
面试怎么答页面慢先拆三段:网络、渲染、交互。网络看瀑布图和 TTFB,渲染看 LCP 和长任务,交互看 INP。三段的手段完全不同,先确定慢在哪一段再优化,否则容易做了一堆改动但指标没动。另外本地 Lighthouse 分数不能代替真实用户数据。
4

内存泄漏

前端看堆快照,Node 看增长曲线
泄漏的特征是内存只涨不跌:反复进出同一个页面,堆占用持续上升,GC 之后回落不到基线。前端用堆快照对比找持有链,Node 用 heapdump 加增长曲线。
前端四种典型泄漏未解绑的事件监听 window.addEventListener 后没 remove 定时器 setInterval 没 clear,回调闭包持有大对象 游离 DOM 从文档移除但 JS 还引用着(Map 里存了节点) 全局缓存无上限 Map 只增不删,key 是用户会话或路由
Node 侧的定位路径1. 看增长 watch -n 5 'ps -o rss= -p <pid>' 或 监控面板的堆曲线 2. 采快照 node --heapsnapshot-signal=SIGUSR2 或 heapdump 3. 对比两次 间隔几分钟各存一份,看哪类对象数量翻倍 4. 找持有链 从可疑对象往上追到 GC root,看是谁在引用
面试怎么答内存泄漏的表现是反复进出同一个功能后堆占用持续上升,GC 后回不到基线。前端常见的是没解绑的事件监听、没清的定时器、游离 DOM 和没有上限的全局缓存,用堆快照对比找持有链。Node 侧是间隔采样两份快照,看哪类对象数量翻倍,再顺引用链追到 GC root。
5

接口问题:先分状态码

4xx、5xx、超时、跨域各自指向不同层
接口报错先看状态码,它能直接定位到哪一层:4xx 是请求本身有问题(前端参数、鉴权、路径),5xx 是服务端问题,超时是链路或性能问题,CORS 报错往往其实是别的问题被掩盖了。
状态码到病因的映射400 参数格式错 / 后端校验未通过 401 token 过期或没带;检查是否有请求漏了拦截器 403 权限不足;注意是"登录了但没权限"不是"没登录" 404 路径错;先确认 proxy_pass 有没有吃掉前缀 413 请求体过大;检查 Nginx client_max_body_size 429 被限流;看 limit_req 配置和调用频率 500 服务端未捕获异常;查后端日志 502 上游不可达 / 响应非法;查进程和端口 504 上游超时;查慢接口 ERR_CONNECTION_REFUSED 端口没监听 CORS 报错 先看 Network 里真实状态码,可能是个 500
面试怎么答看状态码就能定位到层:4xx 是请求侧问题,401 跳登录、403 提示无权限、404 先查网关路径;5xx 是服务端;502 查上游可达性,504 查慢接口。跨域报错要特别小心,它经常是 5xx 响应没带 CORS 头导致的假象,真实状态码要去 Network 里看。
6

Node:CPU 高、内存涨、卡住★

三种症状三种查法
Node 服务的三类问题要分开查:CPU 高看火焰图找热点函数,内存涨看堆快照找持有链,请求变慢但 CPU 不高通常是事件循环被阻塞或外部依赖慢。第三种最容易被误判。
三条排查路径CPU 100% top -Hp <pid> 找到最耗 CPU 的线程 node --prof / clinic flame 生成火焰图,看哪个函数占大头 常见原因:死循环、正则回溯爆炸、大 JSON 序列化、同步加密 内存持续上涨 node --heapsnapshot-signal 采堆快照 常见原因:缓存无上限、全局数组只 push、监听器没移除 CPU 不高但慢 先量事件循环延迟,再查外部依赖 常见原因:同步文件读、大量同步 crypto、下游接口慢
面试怎么答CPU 高就用火焰图找热点,常见是死循环、正则回溯、大 JSON 序列化;内存涨就采堆快照对比找持有链,常见是缓存无上限和监听器泄漏;CPU 不高但慢要先量事件循环延迟,多半是同步操作或下游接口慢。最后这种情况最容易误判成"机器不够",其实是主线程被堵住了。
7

日志与链路追踪★

没有 requestId 就只能靠猜
排查效率的分水岭是能不能把一次请求的所有日志串起来。做法很简单:入口生成 traceId,透传到下游,所有日志都带上它。没有这个,就只能靠时间戳在几万行日志里肉眼找。
面试怎么答排查效率的关键是能把一次请求的日志串起来。做法是入口生成 traceId 并通过 AsyncLocalStorage 透传到所有下游调用,日志里带上它,同时把 traceId 通过响应头返回前端,用户报障时直接给 id 就能精确查询。没有它只能在海量日志里按时间戳猜。
8

复现:最小化与二分

能稳定复现就赢了一半
复现的两个动作:最小化(把触发条件缩到最少)和二分(把范围对半砍)。偶现问题不要试图一次抓住,而是想办法提高复现概率——加日志、加压、模拟慢网络。
固定变量浏览器版本、账号、数据、网络、时间
→
缩小范围去掉无关的页面和数据,只留最小路径
→
二分排查注释一半代码 / 禁用一半功能,看问题还在不在
→
提高概率加压、模拟慢网、改系统时间、并发触发
→
验证根因改掉那一处,确认现象消失且没引入新问题
二分在工程里的几种用法代码二分 git bisect 找到引入问题的那次提交 功能二分 用特性开关逐个关掉,看问题是否消失 数据二分 把出问题的用户数据对半删,缩小到具体记录 环境二分 本地复现 / 预发复现,定位是环境还是代码
面试怎么答复现先固定变量,把浏览器、账号、数据、网络都定住,再最小化路径。范围大就用二分:代码层面用 git bisect 找提交,功能层面用开关逐个关,数据层面对半删。偶现问题不要死等,要想办法提高复现概率,比如加压或者模拟慢网络。
9

止血优先于定位★

顺序错了会扩大影响面
线上故障的第一原则是先止血再定位。回滚、关开关、降级、限流,这些动作能在几分钟内恢复服务,而定位根因可能要几小时。顺序反过来,就是让用户陪着一起等。

止血手段(按速度排)

  • 回滚到上一个版本:最快,前提是产物还在
  • 关特性开关:比回滚更精准,只影响新功能
  • 限流 / 熔断:牺牲部分请求保住整体
  • 降级:关掉非核心功能,如推荐、评论
  • 扩容:能缓解容量问题,但治不了死锁和慢查询

定位手段

  • 看监控指标和错误日志
  • 对比发布记录和配置变更
  • 按 traceId 抽个别请求还原现场
  • 本地或预发环境复现
面试怎么答线上故障先止血再定位。止血手段按速度排:回滚最快,但前提是旧产物还在;关特性开关更精准;限流降级能保住核心链路;扩容只能解容量问题。这些动作要提前演练,故障现场不是第一次点按钮的地方。止血之后必须补真正的根因修复,否则下次发布还会复现。
10

线上和本地不一样

八个最常见的差异源
"本地好的,线上不行"几乎都能归到几类差异上:构建产物、环境变量、数据规模、并发与缓存、网络与时区。按这几个维度对一遍,比漫无目的看代码快得多。
差异清单1. 构建模式 dev 未压缩未 tree-shaking,prod 压缩后有副作用被摇掉 2. 环境变量 接口地址、开关、超时时间不一样 3. 数据量 本地几十条,线上几十万条,分页和查询计划完全不同 4. 并发 本地单请求,线上有竞争、有锁等待 5. 缓存 CDN 和浏览器缓存了旧版本资源 6. 时区与语言 服务器 UTC,用户在东八区,日期显示差一天 7. 依赖版本 锁文件不一致,或容器镜像里是旧版本 8. 权限与网络 线上有网关、WAF、跨域限制,本地直连
面试怎么答本地好线上不行,按几类差异对一遍:构建产物是否一致(压缩和 tree-shaking 会改变行为)、环境变量、数据量级、并发情况、缓存版本、时区、依赖版本、以及线上多出来的网关和 WAF。最容易忽略的是压缩导致的问题,所以要保证预发跑的是生产产物。
11

工具清单

按问题类型挑工具
工具不是越多越好,知道什么症状用什么工具才有用。前端基本靠 DevTools 三件套,Node 靠 inspector 和火焰图,网络层靠 curl 和 tcpdump。
前端Network 请求瀑布、状态码、响应内容、缓存命中 Performance 长任务、布局抖动、调用栈火焰图 Memory 堆快照对比,找泄漏和持有链 Coverage 未使用的 JS/CSS 占比 Lighthouse 综合评分,仅作参考,不代替真实数据
Node 与网络node --inspect 断点调试 / Chrome DevTools 连接 node --prof 生成 v8 log,再用 --prof-process 转成可读报告 clinic flame / doctor 火焰图和综合诊断,比手工分析快 0x 交互式火焰图 ss -lntp 端口和连接的实时状态 tcpdump + wireshark 抓包,看握手、重传、DNS curl -v --resolve 绕过 DNS 和负载均衡直连某台机器
面试怎么答我按症状挑工具:前端看 Network 判断资源层、Performance 找长任务、Memory 找泄漏;Node 用 inspector 断点、用火焰图找 CPU 热点、用堆快照找内存问题;网络层用 ss 看端口、用 curl --resolve 直连单机验证、必要时才上 tcpdump。工具结论要能互相印证。
12

复盘怎么写★

对事不对人,落成机制
好的复盘有三部分:时间线(几点发生了什么、做了什么)、根因(技术原因 + 为什么会漏掉)、改进项(要具体到人和时间)。最没用的复盘是"加强测试意识"这种无法执行的话。
复盘结构1. 影响 多少用户、多长时间、损失什么 2. 时间线 分钟级:发现、响应、止血、恢复 3. 根因 直接原因(代码 bug)+ 根本原因(为什么没被发现) 4. 改进 每条都要有负责人和截止时间,且可验证 5. 反问 如果重来一次,哪一步能提前 10 分钟
面试怎么答复盘分三块:影响和时间线、根因、改进项。根因要问两层——直接原因和为什么没被发现;改进项必须具体到负责人、时间和验收标准,否则就是空话。时间线里要记录"当时判断成了什么",因为判断失误的环节才是最有价值的部分。
13

速答清单

十句话收口
01排查的第一步做什么?
定性:必现还是偶现、影响面、开始时间、最近改了什么。然后把故障时间和发布记录对齐。
02发版后白屏最常见的原因?
旧页面请求旧 hash 的 chunk 得到 404。解法是保留旧产物,或者捕获 ChunkLoadError 后强制刷新一次。
03JS 报 Unexpected token < 说明什么?
大概率是请求 JS 拿到了 HTML,通常是网关把 404 回落成了 index.html,真实原因是路径错了。
04页面慢该怎么拆?
拆成网络、渲染、交互三段。网络看瀑布图和 TTFB,渲染看 LCP 和长任务,交互看 INP。
05Node CPU 不高但请求很慢,先查什么?
先量事件循环延迟。多半是同步操作或下游接口慢把主线程堵住了,加机器没用。
06正则怎么会把 CPU 打满?
嵌套量词遇到长字符串会指数级回溯,单个请求就能吃满一个核。
07CORS 报错但后端没收到请求?
先看 Network 里的真实状态码。5xx 响应如果没带 CORS 头,浏览器只会报跨域,把真实错误盖住了。
08线上故障先止血还是先定位?
先止血。回滚、关开关、限流降级能在几分钟恢复服务,定位可能要几小时。但事后必须补根因修复。
09本地好线上不行,先对哪几项?
构建产物、环境变量、数据量、并发、缓存、时区、依赖版本、网关差异。压缩导致的问题最隐蔽。
10复盘里什么最有价值?
根因的第二层——为什么没被发现——以及时间线里"当时判断成了什么"。改进项必须可验收。