Linux服务器性能排查实战指南|CPU、内存、磁盘、网络一文搞定
服务器卡了,老板问你为什么,你说"我看看",然后敲了一堆命令,最后还是不知道问题在哪。
这篇文章整理了我常用的排查流程和命令,下次遇到性能问题,按这个套路来。
一、排查思路
性能问题无非就是四大资源:
CPU → 计算能力不够
内存 → 空间不够,频繁换页
磁盘 → IO太慢,读写阻塞
网络 → 带宽满了,连接数爆了
排查顺序:先看整体,再定位具体
1. top/htop → 整体概览
2. 定位瓶颈 → CPU/内存/磁盘/网络
3. 找到进程 → 哪个进程在搞事
4. 深入分析 → 为什么这个进程有问题
5. 解决问题 → 优化/重启/扩容
二、整体概览
2.1 top命令
top
关键指标:
load average: 1.52, 1.34, 1.21 # 1/5/15分钟负载
%Cpu(s): 25.3 us, 5.2 sy # 用户态/内核态CPU
KiB Mem: 8000000 total # 内存使用
KiB Swap: 2000000 total # 交换分区
load average怎么看?
单核CPU:
load < 1 → 正常
load = 1 → 刚好满载
load > 1 → 过载
多核CPU(比如4核):
load < 4 → 正常
load = 4 → 刚好满载
load > 4 → 过载
简单算法:load / CPU核数 < 0.7 是健康的
2.2 htop(推荐)
# 安装
yum install htop # CentOS
apt install htop # Ubuntu
# 使用
htop
比top好看,支持鼠标,可以直接杀进程。
2.3 vmstat
vmstat 1 5 # 每秒采样,共5次
输出:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 512000 50000 200000 0 0 10 20 100 200 25 5 70 0 0
关键列:
r:运行队列长度,>CPU核数说明CPU忙b:阻塞进程数,>0说明有IO等待si/so:换入换出,>0说明内存不够用了wa:IO等待占比,>20%说明磁盘慢
三、CPU排查
3.1 确认CPU是瓶颈
# 方法1:top看%Cpu
top
# 方法2:mpstat看每个核
mpstat -P ALL 1 5
# 方法3:sar历史数据
sar -u 1 5
CPU使用率分类:
us (user) → 用户进程,业务代码
sy (system) → 内核,系统调用
wa (iowait) → 等IO,磁盘问题
si (softirq) → 软中断,网络问题
3.2 找到占用CPU的进程
# 方法1:top按CPU排序(默认)
top
# 按P键按CPU排序
# 方法2:ps
ps aux --sort=-%cpu | head -10
3.3 分析进程在做什么
# 查看进程的线程
top -H -p <pid>
# 查看进程状态
cat /proc/<pid>/status
# 查看进程打开的文件
ls -l /proc/<pid>/fd
# 查看进程的系统调用(strace)
strace -p <pid> -c # 统计
strace -p <pid> # 实时跟踪
3.4 Java应用CPU高
# 1. 找到CPU高的Java进程
top
# 2. 找到CPU高的线程
top -H -p <pid>
# 记下线程ID,比如12345
# 3. 转成16进制
printf "%x\n" 12345
# 输出:3039
# 4. jstack查看线程栈
jstack <pid> | grep -A 30 "3039"
四、内存排查
4.1 确认内存情况
# 方法1:free
free -h
# 输出
total used free shared buff/cache available
Mem: 7.6G 2.1G 512M 100M 5.0G 5.2G
Swap: 2.0G 0B 2.0G
怎么看内存够不够?
看available,不是free!
free很小没关系,Linux会用空闲内存做cache
available才是真正可用的内存
available < 总内存10% → 危险
Swap used > 0 → 内存已经不够用了
4.2 找到占用内存的进程
# 方法1:top按内存排序
top
# 按M键按内存排序
# 方法2:ps
ps aux --sort=-%mem | head -10
# 方法3:smem(更准确)
smem -rs pss | head -10
4.3 分析内存使用
# 查看进程内存映射
pmap -x <pid>
# 查看进程内存详情
cat /proc/<pid>/smaps | head -50
# 查看系统内存分布
cat /proc/meminfo
4.4 Java应用内存高
# 查看JVM内存
jmap -heap <pid>
# 查看对象占用
jmap -histo <pid> | head -20
# dump内存分析
jmap -dump:format=b,file=/tmp/heap.hprof <pid>
4.5 内存泄漏排查
# 持续观察内存增长
watch -n 5 "ps -o pid,rss,vsz,comm -p <pid>"
# 如果RSS持续增长不释放,可能是泄漏
五、磁盘排查
5.1 确认磁盘情况
# 磁盘空间
df -h
# 磁盘IO
iostat -x 1 5
iostat输出:
Device r/s w/s rkB/s wkB/s await %util
sda 10 50 100 500 5.0 30.0
关键指标:
%util:>70%说明磁盘忙await:>10ms说明响应慢r/s + w/s:IOPS
5.2 找到占用IO的进程
# 方法1:iotop(推荐)
iotop -o # 只显示有IO的进程
# 方法2:pidstat
pidstat -d 1 5
5.3 找到大文件
# 找大文件
find / -type f -size +100M -exec ls -lh {} \;
# 找大目录
du -sh /* | sort -rh | head -10
# 递归找
du -h --max-depth=2 / | sort -rh | head -20
5.4 磁盘满了怎么办
# 1. 找到大文件
du -sh /* | sort -rh | head -10
# 2. 清理日志
# 找到大日志
find /var/log -type f -size +100M
# 清空日志(不删文件)
cat /dev/null > /var/log/xxx.log
# 3. 清理Docker
docker system prune -a
# 4. 清理包缓存
yum clean all # CentOS
apt clean # Ubuntu
六、网络排查
6.1 确认网络情况
# 网络连接数
ss -s
# 网络流量
sar -n DEV 1 5
# 或者用iftop
iftop -i eth0
6.2 连接数过多
# 查看连接状态分布
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn
# 输出
# 5000 ESTAB → 已建立连接
# 2000 TIME-WAIT → 等待关闭
# 100 CLOSE-WAIT → 对端关闭,本地没关
TIME_WAIT过多:
# 临时优化
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30
CLOSE_WAIT过多:
代码问题!连接没有正确关闭
检查代码里的socket/http连接是否close了
6.3 找到占用带宽的进程
# nethogs(按进程显示流量)
nethogs eth0
# iftop(按连接显示流量)
iftop -i eth0
6.4 网络延迟排查
# ping测试
ping -c 10 <target>
# traceroute路径
traceroute <target>
# mtr综合工具
mtr <target>
6.5 端口占用
# 查看端口被谁占用
ss -tlnp | grep :8080
netstat -tlnp | grep :8080
# 查看进程监听的端口
ss -tlnp | grep <pid>
七、综合排查案例
案例1:服务器卡顿
现象: SSH连接慢,命令响应慢
排查过程:
# 1. 看负载
uptime
# load average: 50.00, 45.00, 40.00 (4核机器,严重过载)
# 2. 看是什么资源不够
top
# 发现 %wa 很高,说明是IO等待
# 3. 看磁盘IO
iostat -x 1
# sda %util: 100% (磁盘满载)
# 4. 找占用IO的进程
iotop -o
# 发现是某个日志进程疯狂写
# 5. 解决
# 检查日志配置,减少日志量
案例2:内存持续增长
现象: Java服务运行几天后OOM
排查过程:
# 1. 确认内存情况
free -h
# Swap已经用了1G,内存吃紧
# 2. 找到进程
ps aux --sort=-%mem | head -5
# Java进程占了6G
# 3. 看JVM内存
jmap -heap <pid>
# 老年代快满了
# 4. dump分析
jmap -dump:format=b,file=/tmp/heap.hprof <pid>
# 用MAT分析,发现某个List一直在增长
# 5. 解决
# 检查代码,修复内存泄漏
案例3:网络连接失败
现象: 服务间调用超时
排查过程:
# 1. 看连接数
ss -s
# TCP: 65000 (estab 60000, closed 5000)
# 2. 看连接状态
ss -ant | awk '{print $1}' | sort | uniq -c
# 50000 TIME-WAIT
# 3. 检查端口范围
sysctl net.ipv4.ip_local_port_range
# 32768 60999 (只有28000个端口)
# 4. 解决
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
sysctl -w net.ipv4.tcp_tw_reuse=1
八、常用命令速查
CPU
top # 整体概览
htop # 更友好的top
mpstat -P ALL 1 # 每个CPU核心
pidstat -u 1 # 每个进程CPU
perf top # CPU热点函数
内存
free -h # 内存概览
vmstat 1 # 内存统计
pidstat -r 1 # 每个进程内存
pmap -x <pid> # 进程内存映射
磁盘
df -h # 磁盘空间
iostat -x 1 # 磁盘IO
iotop -o # IO最高的进程
lsof +D /path # 谁在用这个目录
网络
ss -s # 连接统计
ss -ant # 所有TCP连接
iftop -i eth0 # 实时流量
nethogs eth0 # 每进程流量
tcpdump -i eth0 # 抓包
九、监控告警建议
排查是事后,监控是事前。建议配置:
| 指标 | 告警阈值 |
|---|---|
| CPU使用率 | > 80% 持续5分钟 |
| 内存使用率 | > 85% |
| 磁盘使用率 | > 85% |
| 磁盘IO util | > 80% 持续5分钟 |
| 网络连接数 | > 50000 |
| Load Average | > CPU核数 * 2 |
常用监控方案:
- Prometheus + Grafana
- Zabbix
- 云厂商自带监控
总结
性能排查套路:
1. 先看整体 → top/htop
2. 定位瓶颈 → CPU/内存/磁盘/网络
3. 找到进程 → ps/top排序
4. 深入分析 → strace/jstack/pmap等
5. 解决问题 → 优化代码/调参/扩容
记住几个关键命令:
top/htop- 看整体iostat -x 1- 看磁盘ss -s- 看网络free -h- 看内存
多练几次,下次服务器出问题就不慌了。
有问题评论区交流~

浙公网安备 33010602011771号