Linux性能瓶颈需综合多指标关联分析:CPU高但响应不卡应查runq-sz和cs;iostat中r_await/w_await差异定位读写瓶颈;pgpgin/pgpgout持续>10M/s提示隐性内存压力;TCP重传需netstat与ss联合分析。

Linux系统性能瓶颈不能靠单个指标判断,top 看 CPU 高 ≠ 真正的瓶颈,iostat 显示 %util 100% 也不一定代表磁盘慢——关键在指标间的关联性与时间维度上的变化趋势。
CPU高但响应不卡?先看 runq-sz 和 cs 是否同步飙升
CPU 使用率高,服务却没明显延迟,大概率是任务在就绪队列里排队,而非真正在执行。这时候要查运行队列长度和上下文切换次数:
-
vmstat 1中关注runq-sz(就绪队列长度):持续 > CPU 核数 × 2,说明有大量任务等待调度 -
cs(context switch/sec)异常高(比如 > 50k/s),配合pidstat -w 1查具体进程,常指向频繁唤醒、锁竞争或短生命周期线程泛滥 - 注意区分
sy(system time)占比:若远高于us,问题往往出在内核态,如中断处理、内存回收或驱动阻塞
iostat -x 1 里 await 和 r_await/w_await 的差异必须分清
await 是请求从发出到完成的平均耗时(含排队 + 服务时间),但它掩盖了读写行为的不对称性:
-
r_await高但w_await正常 → 读密集型瓶颈,可能缺缓存、随机读多、或存储介质(如 HDD)响应差 -
w_await高且%util接近 100% → 写限流或后端存储吞吐见顶;但若%util低而w_await高,更可能是文件系统层问题(如 XFS 日志阻塞、ext4 barrier 开启+机械盘) -
avgqu-sz持续 > 1 表示 I/O 请求长期积压,此时await失去参考价值,应结合blktrace或iosnoop定位具体设备/请求模式
内存看似充足,pgpgin/pgpgout 却持续走高?警惕隐性换页压力
free -h 显示可用内存充足,不代表没有内存压力。真正危险的是内核频繁进行页面换入换出:
- 用
vmstat 1观察pgpgin(每秒换入 KB)和pgpgout(每秒换出 KB):持续 > 10M/s 是强信号 - 即使
si/so(swap in/out)为 0,pgpgin高也意味着应用在反复申请/释放内存,触发直接回收(direct reclaim),拖慢分配路径 - 配合
slabtop看kmalloc-*或dentry占用是否异常,常见于未关闭vm.swappiness=0时的脏页回写竞争,或容器环境未设memory.limit_in_bytes
netstat -s 和 ss -i 联合看 TCP 重传,别只盯 retransmit 总数
TCP 重传率升高不等于网络丢包,可能是本地拥塞控制、接收窗口不足或应用读取延迟导致:
-
netstat -s | grep -i "retransmitted"给总量,但需结合ss -i查单连接的retrans字段,确认是否集中在少数长连接上 - 若某连接
retrans高且rcv_space小(如 ss -m 可见rcv_rtt异常大 -
tcprcvdatanotimeout(来自/proc/net/snmp)突增,大概率是应用层 ACK 延迟,而非链路问题
watch -n 1 'echo "=== CPU ==="; vmstat 1 2 | tail -1; echo "=== IO ==="; iostat -x 1 2 | tail -1; echo "=== MEM ==="; vmstat 1 2 | tail -1 | awk "{print \$9,\$10,\$11,\$12}"; echo "=== NET ==="; ss -i | grep -v "State" | head -3'
多维指标不是堆在一起看,而是按「请求路径」串起来:用户请求 → CPU 调度 → 内存分配 → 存储 I/O → 网络收发。漏掉任一环节的时间戳对齐(比如用 perf record -e sched:sched_switch 同步抓取),就容易把果当因。











