Linux 故障排查实战:从现象到定位的系统方法
排查故障最消耗时间的,从来不是敲不出那条命令,而是不知道该敲哪一条。
很多人一遇到线上问题,第一反应就是”重启一下试试”。运气好能恢复,运气不好问题被掩盖,等下周再次爆发时,反而更难查。真正高效的排查,靠的不是命令数量,而是一套稳定的思考路径。
本文把日常最高频的排查动作,整理成一套可以直接套用的框架。
一、先做两件事:确认与止损
1. 确认问题真实存在
在动手排查之前,先回答一个问题:故障是真的,还是误报?
监控告警不等于故障。遇到过这种情况吗:Zabbix 报警说 CPU 飙到 90%,实际上一看是某个定时任务在正常跑批。没有确认就排查,等于在错误的方向上浪费时间。
确认的动作很简单,但经常被跳过:
1 | # 1. 现象能稳定复现吗?还是偶发? |
排查现场的第一原则:先明确边界,再深入细节。 不知道问题范围的排查,等于大海捞针。
2. 必要时先止损
生产环境的排查有个残酷现实:有时候你来不及找到根因,但必须先恢复业务。
1 | # 快速回滚是最高效的止损手段 |
止损和定位是两件事,不要混在一起。先恢复,再慢慢查原因——这对业务负责,也给自己争取了从容排查的时间。
二、分层定位:从下往上逐层排除
这是整套方法论的核心:按固定顺序自底向上排查,不要跳步。
1 | 7.业务层 ← 用户看到的是"打不开",但问题往往不在这里 |
为什么必须自底向上? 因为下层是上层的地基。数据库挂了导致应用报错,如果你先去看应用代码,会浪费大量时间;而实际上重启数据库就好了。
逐层的检查清单:
第 1-2 层:硬件与系统(最容易被忽略)
1 | # 磁盘空间和 inode(inode 耗尽会导致"磁盘还有空间却写不进去") |
排查技巧:top 里按 1 可以展开每个 CPU 核心,M 按内存排序,P 按 CPU 排序。这三个键几乎覆盖了 80% 的场景。
第 3-4 层:服务与依赖
1 | # 服务状态与端口监听 |
依赖层是最容易出”玄学问题”的地方。一次接口超时,可能是自己的服务慢,也可能是下游数据库连接池打满了。先确定是谁的问题,再决定动谁。
第 5-6 层:应用与业务
到了这一层,通常意味着问题已经定位得比较窄了。这时候需要日志:
1 | # 实时跟踪(最常用) |
日志统计是个被严重低估的技巧。 面对几百行报错,直接看会懵;但把错误按类型聚合,出现次数最多的那一条,往往就是根因。
三、四条实战信号:快速缩小范围
如果时间紧张,记不住上面那套分层框架,下面这四个信号能帮你快速判断问题类型。
信号 1:load 很高但 CPU 空闲
1 | uptime # load 高 |
结论:瓶颈在 IO 或磁盘,不在CPU。 常见于 NFS 卡顿、大量小文件读写、备份任务。
信号 2:内存持续增长不释放
1 | free -h # available 持续下降 |
结论:疑似内存泄漏。 短期先重启止损,长期要查代码或调 JVM 参数。
信号 3:连接数打满
1 | ss -s # 查看连接统计 |
结论:连接泄漏或没做连接池。 临时调大端口范围能缓解,根因要在应用层。
信号 4:日志里全是 timeout
结论:优先怀疑依赖服务,而不是本地服务。 先确认依赖是否健康——这是最快的排除法。
四、一份可复用的排查清单
把上面的内容压缩成可打印的清单,贴在工位上:
| 步骤 | 动作 | 关键命令 |
|---|---|---|
| 1 | 确认现象 | 复现条件、影响范围、最近变更 |
| 2 | 评估止损 | 是否需要先恢复业务 |
| 3 | 看系统资源 | free -h df -h uptime |
| 4 | 看磁盘 IO | iostat -x 1 5 |
| 5 | 看服务状态 | systemctl status ss -lntp |
| 6 | 看连接数 | ss -s ss -ant |
| 7 | 看应用日志 | tail -f dmesg -T |
| 8 | 聚合错误 | 统计高频错误找根因 |
| 9 | 定位依赖 | 确认上下游是否健康 |
| 10 | 验证修复 | 复现步骤走一遍 |
五、几个能显著提速的习惯
1. 先看历史
1 | # 上次同类问题怎么解决的? |
同样的问题往往重复发生。 排查前先花五分钟问自己:”以前遇到过吗?”
2. 一次改一个变量
同时改三个配置再观察,等于放弃了归因能力。一次只动一个变量,改完立刻验证,这样才能确定哪个是根因。
3. 记录时间线
排查时随手记时间戳:
1 | 14:32监控报警 CPU 90% |
故障复盘时,这份记录比任何记忆都可靠。排查完不记录的故障,下次还会再查一遍。
4. 别怕重启,但要会重启
在虚拟化环境下,重启几乎是零成本的止损手段。但要知道重启会破坏现场——所以:
- 先抓现场:
top -b -n 1 > /tmp/top.txt、dmesg > /tmp/dmesg.txt - 再重启
- 保留日志,事后分析
结语
排查能力的差距,往往不在于记住多少命令,而在于有没有稳定的路径可循。
新人遇到故障容易慌,因为面对几百条报错不知道从哪看;老手之所以快,是因为他有一套固定的判断顺序——先确认、再止损,然后自底向上逐层排除。
把这篇文章的框架练成肌肉记忆,你排查故障的速度会提升一个量级。
框架是死的,实践是活的。下次遇到具体问题时,试着按这个顺序走一遍,你会发现很多”玄学问题”都能被解释。
相关阅读





