Linux 服务器排障基础教程:从 CPU 飙高到磁盘打满

2026-06-12 14:22:54

Linux 服务器排障基础教程

适用读者:后端开发者、DevOps 工程师,需要在生产环境诊断服务器问题。
预计学习时长:50 分钟 · 含故障模拟练习

学习目标

完成本教程后,你将能够:

  1. 使用 top、htop、vmstat 快速判断系统瓶颈维度
  2. 定位 CPU 飙高、内存泄漏、磁盘打满、网络异常的具体进程
  3. 分析系统日志和应用日志定位故障根因
  4. 掌握常用的应急处理流程
  5. 建立系统化的排障思维框架

前置知识

  • 基本 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/

练习 / 作业

  1. 在测试机上用 stress 工具模拟 CPU 满载,练习定位进程。
  2. 创建一个 1GB 大文件填满 /tmp,练习 dfdu 排查。
  3. journalctl 查看最近 1 小时的系统错误日志。
  4. 配置 logrotate 对一个测试日志文件做按天轮转。
  5. 进阶:编写一个 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。建立「监控告警 → 快速定位 → 止血 → 根因 → 复盘」的流程,才能在生产环境从容应对故障。