Linux服务器故障排查方法论:从现象到根因的完整路径
前言
"服务器连不上了"——这是运维人员最常听到的一句话,也往往是最令人焦虑的开始。面对一个故障,新手可能手足无措,而有经验的工程师则能快速定位问题。差距不在技术,而在于排查方法论。本文总结了一套系统化的故障排查框架,帮助你从容应对各类生产问题。
一、故障排查黄金法则
USE 方法论(Utilization, Saturation, Errors)
对于每个系统资源,检查三个维度:
- 利用率(Utilization):资源使用百分比
- 饱和度(Saturation):排队的任务数量
- 错误(Errors):错误计数
# CPU
utilization: mpstat -P ALL 1 # %usr, %sys
saturation: vmstat 1 # r列(运行队列)
errors: dmesg | grep -i "hardware error"
# 内存
utilization: free -h # used/total
saturation: vmstat 1 # si/so列(swap in/out)
errors: dmesg | grep -i oom
# 磁盘
utilization: iostat -x 1 # %util
saturation: iostat -x 1 # avgqu-sz(平均队列长度)
errors: dmesg | grep -i "I/O error"
RED 方法论(Rate, Errors, Duration)
专用于服务监控:
- 请求速率(Rate)
- 错误率(Errors)
- 延迟(Duration)
# Web服务
tail -10000 /var/log/nginx/access.log | awk '{sum+=$request_time} END {print "avg:", sum/NR, "s"}'
grep " 5[0-9][0-9] " /var/log/nginx/access.log | wc -l
二、问题分层定位法
从底层到上层逐层排查:
第一层:物理/硬件
# 检查硬件错误
dmesg | grep -iE "error|fail|fault|temperature"
# 检查磁盘健康
smartctl -a /dev/sda
第二层:操作系统/内核
# 系统整体负载
uptime
# 内存/CPU/IO概览
vmstat 1 5
# 上下文切换
pidstat -w 1
第三层:网络
# 网络连接状态
ss -s
ss -tan state time-wait | wc -l
# 丢包检查
netstat -i
ping -c 100 gateway | grep loss
第四层:应用层
# 进程状态
ps auxf
systemctl status app-name
# 端口监听
ss -tlnp
lsof -i :8080
三、常见故障场景速查
场景1:CPU使用率100%
# 快速定位
top -c -b -n 1 | head -20
# 找出最耗CPU的进程
ps aux --sort=-%cpu | head -10
# 分析进程在做什么
strace -c -p <PID>
perf top -p <PID>
常见原因:
- 死循环
- 正则表达式灾难性回溯
- 加密/解密操作密集
- 大量日志输出
场景2:内存持续增长(疑似泄漏)
# 按内存排序
ps aux --sort=-%rss | head -20
# 查看进程内存映射
pmap -x <PID> | tail -20
# 查看内存详情
cat /proc/<PID>/smaps | grep -i pss | awk '{sum+=$2} END {print sum/1024 " MB"}'
# 分析OOM日志
dmesg -T | grep -i "out of memory"
场景3:磁盘空间突然满
# 快速定位大目录
du -sh /* 2>/dev/null | sort -rh | head -20
# 查找大文件
find / -type f -size +1G -exec ls -lh {} \; 2>/dev/null
# 检查已删除但未释放的文件
lsof | grep deleted | awk '{sum+=$7} END {print sum/1024/1024 " MB"}'
# 统计inode使用率
df -i
场景4:服务端口不通
排查思路:
应用进程存在吗? → ps aux | grep xxx
端口在监听吗? → ss -tlnp | grep 8080
防火墙开放吗? → iptables -L -n | grep 8080
firewall-cmd --list-all
SELinux阻塞吗? → getenforce
ausearch -m avc -ts recent
绑定地址对吗? → ss -tlnp(看是0.0.0.0还是127.0.0.1)
四、应急响应流程
发现告警/故障
|
┌─────▼──────┐
│ 确认影响范围│
└─────┬──────┘
|
┌─────▼──────┐
│ 快速止损 │ ← 先恢复,后排查
│ (切流/重启) │
└─────┬──────┘
|
┌─────▼──────┐
│ 保留现场 │ ← 导出日志、dump
└─────┬──────┘
|
┌─────▼──────┐
│ 根因分析 │
└─────┬──────┘
|
┌─────▼──────┐
│ 修复&验证 │
└─────┬──────┘
|
┌─────▼──────┐
│ 复盘总结 │
└────────────┘
紧急止损优先于问题排查。如果重启能恢复服务,先重启!不要在生产环境"在线调试"。
五、日志分析技巧
# 按时间段过滤日志
sed -n '/2025-06-20 10:00/,/2025-06-20 10:15/p' app.log
# 统计错误频率
grep "ERROR" app.log | awk '{print $1,$2}' | uniq -c | sort -rn | head -10
# 查看某时间段内慢请求
awk '$4 > 1.0' access.log # 响应时间 > 1s
# 分析日志增长趋势
wc -l app.log.* | sort -rn | head -10
总结
故障排查能力不是一朝一夕练成的,但有了方法论,就有了方向。记住:
- 不要慌:保持冷静,故障不会因为你慌就自动恢复
- 先止损:恢复服务比排查根因更重要
- 记笔记:记录每一步操作,方便复盘
- 建预案:常见的故障要有SOP,紧急时刻不用想
- 多复盘:每次故障都是学习机会