Linux 服务器性能排查实战:从 CPU、内存到磁盘的完整方法论

小小卒子2026-10-20运维⏱ 4min

Linux 服务器性能排查实战:从 CPU、内存到磁盘的完整方法论

线上服务出问题时,最怕的不是故障本身,而是无从下手。本文沉淀一套可复用的 Linux 性能排查方法论:从现象定位到根因分析,每一步都有对应的工具和判断标准。

一、总览:先看整体,再查细节

登录服务器后别急着敲命令,先回答三个问题:负载高不高?谁在消耗?瓶颈在哪?

uptime                       # 负载均值 load average: 0.12, 0.25, 0.30
free -h                      # 内存与 swap 使用
df -h                        # 磁盘空间
dmesg -T | tail -20          # 内核日志,OOM / IO 错误都在这里

load average 的三个数字分别代表 1/5/15 分钟平均负载。判断标准:负载接近 CPU 核数视为满载。例如 8 核机器 load=8 已饱和,load=16 说明有进程在排队等待 CPU。

二、CPU 排查:谁吃掉了我的 CPU?

2.1 实时观测

top                          # 按 P 按 CPU 排序,按 M 按内存排序
htop                         # 更友好的交互界面
mpstat -P ALL 1              # 每核占用率,判断是否单核打满

2.2 定位到线程

top 里看到的进程 PID,进一步定位是哪个线程在烧 CPU:

top -H -p <PID>              # 查看进程内所有线程的 CPU

2.3 抓取线程栈

# 记下 CPU 最高的线程 TID,转为 16 进制
printf "0x%x\n" <TID>
# 抓取该线程的调用栈(Java 用 jstack,C/Go 用 gdb 或 perf)
perf top -p <PID>            # 实时采样函数热点

三、内存排查:从 RSS 到 OOM

free -h                      # total / used / available
vmstat 1 5                   # si/so 大于 0 说明在持续换页,内存告急
ps aux --sort=-rss | head    # 按物理内存占用排序找大户

3.1 OOM Killer 的蛛丝马迹

dmesg -T | grep -i "out of memory"    # 内核 OOM 记录
journalctl -k -f                      # systemd 环境下看内核日志

被 OOM 杀的进程会留下完整记录:进程名、占用内存、触发时刻。常见根因:Java 堆设置超过容器限制、Go 程序缓存无上限、Redis 未设置 maxmemory。

3.2 排查泄漏的工具

# Go 程序
go tool pprof http://localhost:6060/debug/pprof/heap
# Java 程序
jmap -heap <PID>
jstat -gc <PID> 1000 10
# 通用:观察 RSS 是否随流量单调增长

四、磁盘排查:IO 打满与空间告急

4.1 空间问题

df -h                          # 各分区使用率
du -sh /* 2>/dev/null | sort -rh | head -10   # 逐层定位大目录
find /var/log -size +100M -ls  # 找出巨型日志

4.2 IO 性能问题

iostat -x 1                     # %util 接近 100% 说明磁盘饱和
iotop                           # 哪个进程在读写
dstat -d                        # 读写吞吐

IO 饱和典型场景:MySQL 无索引全表扫描、日志写入无缓冲、ES 频繁 merge。定位到进程后结合应用日志分析。

五、网络排查:延迟与连接数

ss -s                          # 连接数统计
ss -t state established | wc -l  # 当前 ESTABLISHED 连接数
netstat -i                     # 网卡丢包率
sar -n DEV 1                   # 网卡吞吐与错误

连接数异常高的排查思路:检查是否有连接泄漏(未释放的连接池)、是否有短连接风暴、是否被攻击(半连接 SYN Flood 用 ss -t state syn-recv 观察)。

六、实战案例:一次 CPU 飙高的完整排障

现象:告警 8 核机器 load 飙到 20,服务响应延迟变大。

排查步骤:

# 1. 确认负载与 CPU
uptime                         # load 20
mpstat -P ALL 1                # 8 个核全部 100%

# 2. 找 CPU 大户
top -o %CPU -n 1 | head        # 发现 java PID 12345 占 780%

# 3. 定位线程与栈
top -H -p 12345 | head         # 线程 22333 最热
printf "0x%x\n" 22333          # 0x573d
jstack 12345 | grep -A 20 0x573d   # 栈指向 JSON 序列化热点

# 4. 确认根因
# 日志显示请求量翻倍,且序列化逻辑存在重复 String 拼接

结论:流量高峰 + 热点代码路径上的低效序列化,双重叠加导致 CPU 饱和。优化序列化实现后负载恢复正常。

七、排查工具箱速查

| 场景 | 首选工具 | 辅助工具 | |------|----------|----------| | 负载高 | uptime / top | mpstat / htop | | CPU 占用 | top -H | perf top / pidstat | | 内存不足 | free / vmstat | dmesg(OOM) / ps rss | | 磁盘空间 | df / du | find | | 磁盘 IO | iostat -x | iotop / dstat | | 网络 | ss / sar -n | netstat / tcpdump | | 应用栈 | jstack / gdb / pprof | perf / flamegraph |

结语

性能排查是"现象 → 数据 → 定位 → 验证"的循环,不是玄学。先把工具链备齐,再按 CPU → 内存 → 磁盘 → 网络 → 应用栈的顺序逐层收敛,大多数问题都能在十分钟内找到突破口。记住:观察要全面,动手要克制,每一步结论都要有数据支撑。

读完了?给作者一点支持

本文采用 CC BY 4.0 协议转载 · © 小卒子

评论区加载中…

🔗 相关文章