问题定位方法论:5W1H分析法、鱼骨图分析法、故障树分析法

说实话,刚带团队那会儿,我最怕的就是线上出问题。

一群人围在屏幕前,你一言我一语,有人说「可能是网络问题」,有人说「我看是代码bug」,还有人拍桌子说「肯定是数据库扛不住了」。折腾半天,问题没定位到,倒是先吵起来了。

后来我慢慢悟出一个道理:排查问题,不能靠猜,得靠方法。

今天我就把自己压箱底的三个分析法拿出来聊聊。它们帮我解决过不少棘手的线上故障,希望你也能用上。

一、5W1H分析法:把问题问透

5W1H,说白了就是六个问题:What、Why、Where、When、Who、How。

我习惯在接到故障报告后,先不急着看代码,而是拿张纸把这六个问题写下来。你想想看,很多时候我们定位慢,不是因为技术不行,而是因为问题本身就没描述清楚。

5W1H 问题清单(我常用的模板)
维度 问题示例 我的经验
What(什么) 发生了什么异常?错误码是什么? 别只看「报错了」,要具体到错误信息
Why(为什么) 为什么会出现这个现象? 这一步容易变成猜,先记下来,后面验证
Where(哪里) 哪个模块?哪个接口?哪台机器? 我遇到过只报「服务不可用」,结果查了半天是负载均衡配置错了
When(何时) 首次出现时间?是否周期性? 时间点往往能关联到发布或变更
Who(谁) 谁影响的?谁发现的? 别忽略「谁发现的」,目击者描述有时比日志更关键
How(如何) 如何复现?复现步骤是什么? 不能复现的问题,基本等于没定位

举个例子。有一次线上支付接口超时,团队里有人直接去查数据库慢查询。我拦住了他们,先问了一圈:

  • What:接口返回 504,错误日志是「upstream timeout」
  • Where:只发生在订单金额大于 5000 元的请求上
  • When:每次都是下午 3 点左右开始,持续半小时
  • How:用 curl 模拟大额订单,必现

你看,问完这几个问题,方向就清晰了——不是数据库问题,而是某个定时任务在下午 3 点跑,占用了大量资源,导致大额订单处理超时。最后发现是风控系统的对账任务在作怪。

我的小技巧:5W1H 不要一次性问完。先问 What、Where、When,快速缩小范围。Why 留到最后,因为「为什么」最容易让人先入为主。

二、鱼骨图分析法:把原因找全

5W1H 帮我们把问题描述清楚了,但原因分析呢?

这时候我常用鱼骨图。说白了,就是画一条鱼骨头,鱼头是问题,鱼刺是各类原因。

我个人习惯把原因分成六大类,也就是所谓的 5M1E:

  • 人(Man):操作失误、配置错误
  • 机器(Machine):硬件故障、资源不足
  • 材料(Material):数据异常、依赖服务问题
  • 方法(Method):流程缺陷、代码逻辑错误
  • 测量(Measurement):监控缺失、日志不全
  • 环境(Environment):网络波动、机房问题

嗯,这里要注意:鱼骨图不是让你一次画完的。我建议先头脑风暴,把所有可能的原因都列出来,然后再逐一验证。

我曾经踩过的坑:有一次系统频繁 OOM,团队画了鱼骨图,列了十几条原因。结果查了两天,最后发现是某个同事在代码里用了 ThreadLocal 没清理,导致内存泄漏。鱼骨图里「方法」这一条其实写到了,但被大家忽略了。所以啊,鱼骨图只是帮你「想到」,不能帮你「找到」。

下面是我画的一个鱼骨图示例,展示「API 响应慢」的可能原因:

API 响应慢 人 配置错误 操作失误 机器 CPU 满载 内存不足 方法 SQL 慢查询 循环调用 材料 数据量大 缓存失效 环境 网络延迟 依赖服务超时 测量 监控缺失 日志不全
使用建议:鱼骨图适合团队一起画。每个人写几个可能原因,贴在白板上,然后归类。你会发现,很多你没想到的点,别人一句话就点醒了。

三、故障树分析法:把逻辑理清

如果说鱼骨图是「横向找原因」,那故障树就是「纵向挖根因」。

故障树的核心思路很简单:从顶层故障开始,逐层向下分解,直到找到最基本的故障事件。

我举个例子。假设顶层故障是「用户登录失败」,我们一步步往下拆:

用户登录失败
├── 账号问题
│   ├── 账号不存在
│   ├── 账号被锁定
│   └── 密码错误
├── 系统问题
│   ├── 认证服务宕机
│   │   ├── 进程崩溃
│   │   └── 资源耗尽
│   ├── 网络不通
│   │   ├── DNS 解析失败
│   │   └── 防火墙拦截
│   └── 数据库异常
│       ├── 连接池满
│       └── 主从延迟
└── 客户端问题
    ├── Token 过期
    └── 版本不兼容

你看,这样一拆,排查路径就清晰了。从根节点开始,一层层验证,直到找到叶子节点。

我的实战经验:有一次线上告警「订单创建成功率下降」。我用故障树一拆,发现「支付回调超时」是其中一个分支。再往下拆,「回调超时」又分为「网络延迟」和「回调处理慢」。最后定位到是回调处理逻辑里有个 for 循环,每次都要查一次数据库,并发一高就堵住了。修复方案很简单——加个缓存就解决了。

故障树的好处是:它强迫你按逻辑走,而不是跳来跳去。很多人排查问题喜欢「跳跃式思考」,看到 A 现象就跳到 B 原因,结果绕了一大圈又回到原点。故障树能帮你保持清醒。

注意事项:故障树不要画得太深。一般来说,3-4 层就够了。再往下,要么是代码细节,要么是硬件底层,排查成本太高。我一般画到「能通过日志或监控直接验证」的程度就停。

三种方法怎么选?

你可能会问:那我到底用哪个?

我的建议是:

  • 刚接到故障:先用 5W1H 把问题描述清楚。别急着分析,先问清楚「发生了什么」。
  • 需要找全原因:用鱼骨图。特别是团队协作时,鱼骨图能让大家把想法都倒出来。
  • 需要理清逻辑:用故障树。尤其是复杂故障,一层层拆解,不容易遗漏。

说白了,这三种方法不是互斥的,而是互补的。我自己的习惯是:先用 5W1H 问清楚,再用鱼骨图找全原因,最后用故障树深入验证。

最后说一句:方法再好,也得动手。我见过太多人,方法论背得滚瓜烂熟,真到线上出问题了,还是凭感觉乱猜。所以,平时多练练,拿历史故障当案例,画几张图,慢慢就形成肌肉记忆了。

可可精品资料库