进程与性能排查实战:从 ps/top 到负载分析
进程与性能排查实战:从 ps/top 到负载分析
“服务器变慢了”是运维收到最多的反馈,但它背后可能是 CPU、内存、磁盘 IO、网络任意一环的问题。这篇把排查思路和工具串成一条完整的链路,遇到问题按顺序走,很少会抓瞎。
一、排查思路:先定位资源,再定位进程
标准四问:
- 谁在吃 CPU?→
top/ps aux --sort=-%cpu - 谁在吃内存?→
free -h/top/ps aux --sort=-%mem - 谁在等 IO?→
top(看 D 状态)/iostat - 谁在占端口/文件?→
lsof/ss
二、ps:进程快照
1 | ps aux # 完整信息(%CPU %MEM STAT) |
STAT 列是重点——它直接告诉你进程卡在哪:
| 状态 | 含义 | 排查提示 |
|---|---|---|
| R | 运行/排队等 CPU | 结合 %CPU 看是否异常 |
| S | 睡眠等事件 | 正常 |
| D | 不可中断的磁盘等待 | 磁盘有问题(NFS 挂、磁盘故障),kill 不掉 |
| Z | 僵尸进程 | 父进程没 wait() 收尸,找父进程处理 |
| T | 被暂停 | 如 Ctrl+Z |
三、top:动态监控
1 | top |
负载的判读:load average: 12.50, 8.30, 4.20 是 1/5/15 分钟平均负载。负载要和 CPU 核数对比:
1 | nproc # 查看核数 |
CPU 各列关注 wa(iowait)和 si(软中断):wa > 20% 立刻查磁盘 IO(iostat);si 高说明网络流量大,查网卡和连接数。
内存看 free -h,重点盯 si/so(swap 换入换出):vmstat 1 如果 si/so 持续非零,说明内存吃紧在疯狂换页,要扩容或优化应用。
四、lsof:谁占用了什么
1 | lsof -i :80 # 谁在监听 80 端口 |
经典场景:rm 了大日志但 df -h 空间没变——进程还持有文件句柄,文件没真正释放。解决:重启进程,或 > /proc/进程PID/fd/句柄号 清空。
五、一次 Java 线程高 CPU 排查实录
现象:业务反馈接口 P99 飙升,top 看到 java 进程 CPU 400%(占满 4 核)。
排查链路:
top -Hp 1234找到最耗 CPU 的线程 PID(比如 3039);- 转十六进制:
printf "%x\n" 3039→bdf; jstack 1234 | grep -A20 'nid=0xbdf'→ 定位到具体业务线程和代码行;- 发现是某个批量任务循环里不断创建连接未释放,上线前压测没覆盖到;修复后二次压测,CPU 回到 20% 以内。
六、工具补充记忆点
pidstat -u 2 5:每 2 秒采样 5 次看进程 CPU;-d看 IO;-w看上下文切换(自愿切换多=在等锁/IO,非自愿多=CPU 竞争激烈)pmap -x <pid>:进程内存分布/proc/cpuinfo、/proc/meminfo、/proc/loadavg、/proc/<pid>/cmdline:最底层数据来源,没有工具时直接读这里
排查性能问题没有银弹,但固定这套”先资源、后进程、再线程”的顺序,大部分问题都能在半小时内定位到根因。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LuminDream's Blogs!


