1. Linux性能排查全景图
第一次在凌晨三点被运维报警叫醒时,我盯着满屏的性能指标完全不知所措。那个不眠夜让我明白:性能问题就像森林火灾,必须快速定位起火点才能有效扑救。经过多年实战,我总结出这套四维排查体系,它能帮你像老猎人追踪猎物一样,从蛛丝马迹中找到性能瓶颈的真正源头。
现代Linux系统是个精密运转的有机体,CPU、内存、IO、网络四大子系统如同人体的循环系统,彼此关联又相互制约。真正的性能专家不会孤立地看待某个指标,而是掌握"观察现象→定位子系统→验证假设→根治问题"的完整方法论。下面这张排查路线图值得存入你的终端备忘录:
code复制性能现象 → 初步判断 → 关键命令
-------------------------------------------------------
响应延迟高 → CPU/IO → top/vmstat/iostat
进程崩溃 → 内存 → free/smaps/oom_score
传输速度慢 → 网络 → ss/iftop/tcptrace
磁盘警告 → 存储 → iotop/df/du
资深运维的直觉:当SSH连接都变慢时,先查内存再查CPU;当数据库查询超时,先看磁盘IO再看网络流量。这个经验法则能节省大量排查时间。
2. CPU性能深度剖析
2.1 从load average看CPU压力
上周遇到个典型案例:某台16核服务器load average长期保持在25左右,但CPU使用率显示只有30%。新手可能会误判为CPU空闲,实则这是典型的IO等待瓶颈。理解这三个数字的真正含义至关重要:
- 1分钟负载:突发现象的晴雨表,超过CPU核数2倍需警惕
- 5分钟负载:稳态指标,持续高于核数80%说明资源不足
- 15分钟负载:长期趋势,用于判断基线是否漂移
实操中要结合vmstat 1的r列(运行队列)和b列(阻塞进程):
bash复制$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
12 2 244184 125668 284484 1028304 0 0 102 32 102 256 18 6 62 14 0
当r值持续大于CPU核数,且wa(io等待)超过20%,就该检查磁盘性能了。
2.2 火焰图:CPU热点定位神器
去年优化某金融系统时,通过火焰图发现一个看似无害的日志函数竟消耗了15%的CPU。安装perf工具并生成火焰图只需三步:
bash复制# 安装依赖
sudo apt install linux-tools-common linux-tools-generic
# 采集数据(30秒)
sudo perf record -F 99 -a -g -- sleep 30
# 生成SVG图
sudo perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg
分析时要特别关注:
- 宽平顶:表示热点函数
- 陡峭塔尖:可能是锁竞争
- 锯齿状:暗示频繁上下文切换
真实案例:某电商平台通过火焰图发现JSON序列化消耗40%CPU,改用protobuf后QPS提升3倍
3. 内存问题排查实战
3.1 当free显示内存耗尽时
看到free命令输出只剩几十MB内存?别慌!Linux的内存管理策略会让它尽可能利用所有空闲内存作缓存。真正需要关注的是这些指标:
bash复制$ watch -n 1 "free -h; echo; grep -E 'Dirty|Writeback' /proc/meminfo"
total used free shared buff/cache available
Mem: 62G 5.1G 512M 3.2G 56G 53G
Swap: 4.0G 1.2G 2.8G
Dirty: 432 kB
Writeback: 0 kB
关键警戒线:
- Available < 10%总内存:需要干预
- Swap used > 30%:存在内存泄漏风险
- Dirty > 10%内存:可能有IO瓶颈
3.2 OOM杀手日志分析
内存泄漏就像定时炸弹,OOM Killer的日志是破案关键:
bash复制dmesg -T | grep -i oom
[Fri Jul 12 03:45:21 2024] Out of memory: Killed process 21534 (java)
[Fri Jul 12 03:45:21 2024] memory: usage 62914560kB, limit 62914560kB, failcnt 2451
[Fri Jul 12 03:45:21 2024] memory+swap: usage 65011712kB, limit 65011712kB, failcnt 0
通过/proc/[pid]/oom_score可以预判哪些进程会被优先杀死:
bash复制ps -eo pid,comm,oom_score | sort -k3 -nr | head
救命技巧:临时缓解OOM可以执行
echo 1 > /proc/sys/vm/drop_caches,但这只是权宜之计
4. 磁盘IO性能攻坚
4.1 发现隐藏的IO瓶颈
某次MySQL性能诊断中,iostat显示磁盘利用率只有40%,但实际业务已经卡死。原来是被%util指标误导了!更可靠的判断组合应该是:
bash复制$ iostat -x 1
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
vda 15.00 28.00 120.00 224.00 0.00 4.00 0.00 12.50 0.80 1.20 0.05 8.00 8.00 0.60 2.60
关键指标解读:
- r_await/w_await > 10ms:磁盘响应慢
- aqu-sz > 1:存在IO队列堆积
- %util > 70%:需要考虑升级硬件
4.2 文件描述符泄漏排查
文件描述符泄漏就像沙漏漏洞,用这些命令定位问题进程:
bash复制# 查看系统总量
cat /proc/sys/fs/file-nr
# 按进程排序
ls -l /proc/*/fd | awk '{print $NF}' | sort | uniq -c | sort -nr | head
# 查看某进程详情
ls -l /proc/1234/fd | wc -l
我曾用lsof +L1发现某Python进程持有2000多个已删除日志文件的描述符,原因是未正确关闭文件句柄。
5. 网络性能调优指南
5.1 连接状态分析术
TCP连接状态藏着无数秘密,这个ss命令组合是我的最爱:
bash复制ss -antp | awk 'NR>1 {print $1}' | sort | uniq -c
172 ESTAB
3 LISTEN
25 TIME-WAIT
异常状态处理方案:
- 大量SYN-RECV:可能遭受SYN Flood攻击
- TIME-WAIT > 1000:需要调优tcp_tw_reuse
- CLOSE-WAIT堆积:检查应用是否未正确关闭连接
5.2 带宽黑洞定位
当网络吞吐突然下降时,用iftop和tcptrace组合定位:
bash复制# 安装诊断工具
sudo apt install iftop tcptrace
# 实时流量监控
sudo iftop -P -N -n -i eth0
# 抓包分析(10秒)
sudo tcpdump -w /tmp/dump.pcap -i eth0 -G 10 -W 1
tcptrace -l /tmp/dump.pcap
去年我们通过这种方式发现某台Kafka服务器网卡协商速率意外降到了100Mbps,更换网线后吞吐量立即恢复。
6. 性能问题排查工具箱
6.1 我的终端快捷键清单
这些alias定义让排查效率提升3倍:
bash复制alias cpuwatch='watch -n 1 "ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -n 10"'
alias memwatch='watch -n 1 "ps -eo pid,comm,rss,vsz --sort=-rss | head -n 10"'
alias iotop='sudo iotop -o -P -d 5'
alias tcpstate="ss -ant | awk 'NR>1 {print \$1}' | sort | uniq -c"
6.2 性能数据记录脚本
这个脚本自动收集关键指标,生成HTML报告:
bash复制#!/bin/bash
LOG_DIR=/tmp/perf_$(date +%Y%m%d_%H%M%S)
mkdir -p $LOG_DIR
# 基础信息
uname -a > $LOG_DIR/system.info
lscpu > $LOG_DIR/cpu.info
free -h > $LOG_DIR/mem.info
# 持续采集(30秒)
vmstat 1 30 > $LOG_DIR/vmstat.log &
iostat -x 1 30 > $LOG_DIR/iostat.log &
iftop -t -s 30 -n -N -P > $LOG_DIR/iftop.log &
wait
echo "诊断数据已保存至 $LOG_DIR"
7. 真实案例复盘
7.1 数据库响应慢之谜
现象:MySQL查询时快时慢,CPU和内存指标正常
排查过程:
iostat -x 1发现磁盘await波动剧烈iotop定位到有个备份进程间歇性写入pidstat -d 1确认是rsync导致IO竞争
解决方案:通过ionice调整IO优先级
bash复制ionice -c2 -n7 -p $(pgrep rsync)
7.2 容器化应用OOM分析
现象:K8s Pod频繁重启,日志显示OOM
关键证据:
bash复制kubectl describe pod web-xxx | grep -A10 OOM
docker inspect --format='{{.State.Pid}}' container_id
cat /proc/[pid]/status | grep oom_score
最终发现是JVM未正确配置MaxRAMPercentage参数,导致容器内存限制失效。