Linux 服务器排障基础教程:从 CPU 飙高到磁盘打满
2026-06-12 14:22:54
Linux 服务器排障基础教程
适用读者:后端开发者、DevOps 工程师,需要在生产环境诊断服务器问题。
预计学习时长:50 分钟 · 含故障模拟练习
学习目标
完成本教程后,你将能够:
- 使用 top、htop、vmstat 快速判断系统瓶颈维度
- 定位 CPU 飙高、内存泄漏、磁盘打满、网络异常的具体进程
- 分析系统日志和应用日志定位故障根因
- 掌握常用的应急处理流程
- 建立系统化的排障思维框架
前置知识
- 基本 Linux 命令行操作(cd、grep、tail、ps)
- 了解进程、端口、文件系统基本概念
- 有 SSH 远程登录服务器经验
第一章:排障思维框架
1.1 USE 方法论
对每个资源(CPU、内存、磁盘、网络),检查:
- Utilization(利用率):资源使用百分比
- Saturation(饱和度):是否有排队等待
- Errors(错误):是否有错误计数
1.2 排障顺序
1. 确认影响范围(单机?集群?全部用户?)
2. 查看监控大盘(Grafana/Prometheus)
3. 登录问题机器,自上而下排查
4. 保留现场(日志、core dump、堆栈)
5. 止血 → 定位 → 修复 → 复盘
1.3 第一分钟命令
# 系统概览
uptime
# load average: 8.5, 7.2, 6.1(16 核机器则偏高)
# 资源快照
top -bn1 | head -20
free -h
df -h
ss -tlnp
第二章:CPU 问题排查
2.1 识别 CPU 瓶颈
# 实时查看(按 P 排序 CPU)
top
# 更友好的界面
htop
# 每 2 秒采样
vmstat 2 5
# r 列 > CPU 核数 → CPU 饱和
# us 高 → 用户态 CPU 高
# wa 高 → IO 等待(磁盘瓶颈)
2.2 定位高 CPU 进程
# 找 CPU 最高的进程
ps aux --sort=-%cpu | head -10
# 查看 Java 进程线程级 CPU
top -Hp <pid>
# 将高 CPU 线程 ID 转十六进制
printf '%x
' <thread_id>
# Java 线程堆栈
jstack <pid> | grep -A 30 <hex_thread_id>
2.3 典型案例
案例:Java 应用 CPU 100%
# 1. 找到进程
jps -l
# 2. 找到高 CPU 线程
top -Hp 12345
# 3. 导出堆栈
jstack 12345 > thread_dump.txt
# 4. 分析:常见原因
# - 死循环
# - 频繁 Full GC
# - 正则表达式回溯
# - 加密计算
案例:wa(IO Wait)高
说明瓶颈在磁盘而非 CPU:
iotop -o
# 找到读写最多的进程
iostat -xz 2
# %util 接近 100% 的磁盘是瓶颈
第三章:内存问题排查
3.1 理解 Linux 内存
free -h
# total used free shared buff/cache available
# Mem: 16Gi 14Gi 200Mi 100Mi 2.0Gi 1.5Gi
- available 才是真正可用内存(含可回收的 cache)
- 不要只看 free:Linux 会用空闲内存做 cache
3.2 OOM(内存耗尽)
# 查看 OOM 日志
dmesg | grep -i "out of memory"
journalctl -k | grep -i "oom"
# 查看被 OOM Kill 的进程
dmesg | grep "Killed process"
3.3 定位内存泄漏
# 进程内存排名
ps aux --sort=-%mem | head -10
# 查看进程内存详情
pmap -x <pid> | tail -1
# Java 堆内存
jmap -heap <pid>
jmap -histo:live <pid> | head -20
3.4 应急处理
# 清理 page cache(谨慎使用)
sync && echo 3 > /proc/sys/vm/drop_caches
# 临时限制进程内存(cgroup)
systemctl set-property myapp.service MemoryMax=2G
第四章:磁盘问题排查
4.1 磁盘空间
df -h
# 使用率 100% 的挂载点
# 找大文件
du -sh /* 2>/dev/null | sort -rh | head -10
du -sh /var/log/* | sort -rh | head -10
# 找大于 100MB 的文件
find / -xdev -type f -size +100M 2>/dev/null | head -20
4.2 常见磁盘打满原因
| 原因 | 路径 | 处理 |
|---|---|---|
| 日志未轮转 | /var/log/ | 配置 logrotate |
| Docker 镜像/容器 | /var/lib/docker | docker system prune |
| 应用日志 | /app/logs/ | 清理 + 配置轮转 |
| 临时文件 | /tmp/ | 清理过期文件 |
| core dump | /var/crash/ | 限制 core 大小 |
# Docker 清理
docker system df
docker system prune -a --volumes
# 日志轮转配置
cat /etc/logrotate.d/myapp
4.3 inode 耗尽
df -i
# IUse% 100% 但空间未满 → 大量小文件
# 找 inode 最多的目录
find /var -xdev -type f | cut -d/ -f1-4 | sort | uniq -c | sort -rn | head
第五章:网络问题排查
5.1 连接状态
# 监听端口
ss -tlnp
# 连接统计
ss -s
# TIME_WAIT 过多
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
5.2 网络连通性
# DNS 解析
dig example.com
nslookup example.com
# 端口连通
nc -zv db.internal 5432
curl -v http://localhost:8080/health
# 路由追踪
traceroute api.example.com
mtr api.example.com
5.3 流量分析
# 实时流量
iftop -i eth0
# 按连接查看
nethogs
# 抓包(谨慎使用,文件会很大)
tcpdump -i eth0 port 8080 -c 100 -w capture.pcap
第六章:日志分析
6.1 系统日志
# systemd 日志
journalctl -u myapp --since "1 hour ago" -f
journalctl -u myapp --since today | grep -i error
# 传统 syslog
tail -f /var/log/syslog
tail -f /var/log/messages
6.2 应用日志
# 实时跟踪
tail -f /app/logs/app.log
# 搜索错误
grep -i "error|exception|fatal" /app/logs/app.log | tail -50
# 按时间范围
sed -n '/2026-06-12 14:00/,/2026-06-12 15:00/p' /app/logs/app.log
6.3 日志分析技巧
# 统计错误类型分布
grep "ERROR" app.log | awk '{print $5}' | sort | uniq -c | sort -rn
# 统计 API 响应时间
grep "duration" app.log | awk '{print $NF}' | sort -n | tail -20
第七章:应急处理清单
# 1. 服务无响应 → 重启
systemctl restart myapp
# 2. 流量过大 → 限流/降级
# 在 Nginx/网关层限流
# 3. 磁盘满 → 紧急清理日志
find /app/logs -name "*.log" -mtime +7 -delete
# 4. 内存不足 → 重启内存大户
kill -15 <pid> # 先 SIGTERM
sleep 5
kill -9 <pid> # 仍不退出则 SIGKILL
# 5. 保留现场
tar czf incident-$(date +%Y%m%d%H%M).tar.gz /app/logs/ /var/log/
练习 / 作业
- 在测试机上用
stress工具模拟 CPU 满载,练习定位进程。 - 创建一个 1GB 大文件填满 /tmp,练习
df和du排查。 - 用
journalctl查看最近 1 小时的系统错误日志。 - 配置 logrotate 对一个测试日志文件做按天轮转。
- 进阶:编写一个 shell 脚本,采集 CPU/内存/磁盘/负载并输出告警。
FAQ
Q:load average 多少算高?
A:超过 CPU 核数说明有进程在排队。8 核机器 load > 8 需关注。
Q:可以直接 kill -9 吗?
A:先尝试 SIGTERM(-15),给进程优雅退出机会。仅在无响应时用 -9。
Q:生产环境可以装 htop/iotop 吗?
A:可以,这些是只读诊断工具。避免安装不必要的网络服务。
Q:如何防止磁盘再次打满?
A:配置 logrotate、监控告警(磁盘 > 80% 通知)、定期清理策略。
Q:排障时需要停服务吗?
A:优先不停服。先采集日志和堆栈,确认影响范围后再决定是否重启。
小结
Linux 排障的核心是 USE 方法论 + 正确的工具链。CPU 问题看 top/jstack,内存问题看 free/OOM 日志,磁盘问题看 df/du/logrotate,网络问题看 ss/curl/tcpdump。建立「监控告警 → 快速定位 → 止血 → 根因 → 复盘」的流程,才能在生产环境从容应对故障。