Linux 服务器进程占用过高如何定位

Linux 服务器进程占用过高如何定位

“进程占用过高”通常指以下几种情况之一(按严重程度排序):

  1. 某个进程 CPU 使用率持续很高(单核/多核接近 100%)
  2. 某个进程内存占用(RSS / VSZ)持续线性增长或占比异常大
  3. 某个进程打开的文件描述符(fd)数量爆炸
  4. 某个进程产生大量磁盘 IO、线程数过多、上下文切换爆炸等间接导致系统整体变慢

以下是目前最常用、最有效的一套分层定位流程,从 30 秒粗筛到深度分析,通常 5–30 分钟内可以锁定主要嫌疑进程和原因类型。

第一步:30 秒粗筛

顺序命令看什么(异常阈值参考)指向的方向
1top 或 htop按 P 看 %CPU,按 M 看 %MEM,按 1 看多核均衡性CPU / 内存 Top 进程
2ps -eo pid,ppid,%cpu,%mem,rss,vsz,comm –sort=-%cpu | head -15%cpu、rss(驻留内存 KB)、vsz(虚拟内存 KB)CPU / 内存 Top 进程(更精确排序)
3top → 按 t 切换到线程视图看是否某个进程下多个线程同时吃 CPU多线程程序哪个线程在消耗
4mpstat 1 5 或 mpstat -P ALL 1 5每个核 %usr + %sys 是否均衡?是否有单核 100%单核热点 vs 多核均衡负载

一句话判断模板(跑完这几条后写出来):

“8 核机器,top 显示 java 进程 %CPU 780%(接近 8 核满载),rss 12.8G,mpstat 看到 cpu4–7 持续 95–100%,其他核 10–30% → 疑似 java 进程计算密集 + 线程绑定不均”

第二步:按占用类型分类定位

占用类型典型 top/htop 画面特征关键指标阈值参考下一秒最有用命令常见罪魁祸首
CPU 用户态密集%CPU 接近 100% × 核数,us 很高,单个/少量进程单进程 %CPU > 90–100% × 核数pidstat -u 1 5 | sort -k8 -nr perf top死循环、正则匹配、加密/压缩、数值计算
CPU 内核态密集sy 很高(>30–60%),us 不高sy > 30–50%,softirq 高mpstat 1 5 cat /proc/softirqs高 PPS 网络包、iptables 规则多、ksoftirqd
内存占用爆炸RSS / %MEM 持续线性增长或占比 > 50–80%available 下降,swap 开始使用ps -eo pid,rss,vsz,cmd –sort=-rss | head smem -t -k内存泄漏、大对象缓存、Java 堆外内存
线程数爆炸进程 %CPU 不高,但 NLWP(线程数)几千上万ps -eLf | grep PID | wc -l > 1000–5000ps -eLf | awk ‘{print $2}’ | sort | uniq -c | sort -nr线程池不回收、频繁创建线程、连接池耗尽
文件描述符爆炸lsof -p PID | wc -l 几千上万ulimit -n 限制被打满lsof -p PID | awk ‘{print $NF}’ | sort | uniq -c | sort -nrsocket 泄漏、未关闭文件、大量日志句柄
磁盘 IO 间接拉高负载wa/iowait 高,%util 高,但 CPU 不满iostat %util > 80–90%,await > 10–30msiotop -o pidstat -d 1 5日志狂写、数据库 WAL/binlog 同步写

第三步:锁定热点函数 / 代码位置

场景推荐工具与命令输出价值适用语言 / 场景
通用 CPU 热点perf top 或 perf record -F 99 -p PID -g — sleep 30 → 生成火焰图火焰图直观显示热点函数、调用栈C/C++/Rust/Go/Java(需符号表)
Java 进程async-profiler(最推荐) ./profiler.sh -d 30 -f flame.html PID支持 JIT、锁、GC、线程状态火焰图Java / Kotlin / Scala
Python 进程py-spy top / py-spy record -p PID -o flame.svg –duration 30采样火焰图,无需修改代码Python(包括 GIL 瓶颈)
Node.jsnode –prof PID → node –prof-process isolate-*.log -o flame.svgV8 优化器 / GC / 事件循环热点Node.js
高上下文切换 / 锁等待perf record -e syscalls:sys_enter_futex … 或 bpftrace 追踪 futex/mutex显示锁等待时间分布、持有者多线程程序、数据库连接池

火焰图解读小技巧

  • 宽块 = 占用 CPU 时间长
  • 高块 = 调用栈深
  • 平顶 = 叶子函数在吃 CPU(死循环、正则、加密等)
  • 红色/橙色区域多 = 锁等待或 GC 暂停

第四步:临时缓解 + 根因闭环

临时止血常用手段(按风险从低到高):

  1. taskset -c 0-3,8-11 PID → 绑核减少争抢(慎用)
  2. renice -n -10 -p PID 或 chrt -r -p 20 PID → 提高优先级
  3. kill -STOP PID → 暂停观察系统是否恢复
  4. 重启进程 / 容器(最常见操作,但要确认无状态或有主从)

根因闭环检查清单

  • 是否业务高峰正常现象?
  • 是否近期代码/配置/依赖升级引起?
  • 是否资源超卖(云主机 steal 高)?
  • 是否需要加机器 / 拆分服务 / 优化算法?

一句话核心思路

先用 top / pidstat / mpstat 粗筛占用类型 → 再根据类型选 perf / async-profiler / py-spy 等工具生成火焰图 → 最后结合业务代码 / 配置 / 锁定位根因

Telegram
Telegram@IDCSELL