linux cpu 长期100%需先区分用户态(%us高)或内核态(%sy高)耗尽,再用top/ps/pidstat定位高占用进程与线程,结合jstack、show processlist、strace等分析根因,最后通过cpulimit或cgroups限频应急,并部署prometheus+node_exporter长期监控。

Linux 系统 CPU 使用率长期维持在 100%,通常不是“CPU 不够用”这么简单,而是某个或某几个进程、线程异常占满资源,或内核层面存在调度、锁、中断等瓶颈。快速定位关键线索比盲目重启更有效。
确认是用户态还是内核态耗尽 CPU
运行 top 或 htop,观察顶部的 %us(user) 和 %sy(system) 比例:
- 若 %us 高(如 >80%):问题大概率出在某个用户进程(如 Java 应用死循环、Python 脚本未设 sleep、Node.js 同步阻塞操作)
- 若 %sy 高(如 >50%):说明内核工作繁重,常见于频繁系统调用、软中断堆积(如网卡收包过载)、spinlock 争用、或内核模块 bug
- 同时看 %wa(iowait)是否很低:如果接近 0,基本可排除磁盘 I/O 瓶颈导致的假性高 CPU
找出真正吃 CPU 的进程和线程
使用以下命令逐层下钻:
-
top -H -p
:进入线程视图,查看指定进程内的哪个线程(LWP)占用最高(注意开启线程模式:按 H 切换) - ps -eo pid,ppid,lwp,comm,%cpu --sort=-%cpu | head -20:列出 CPU 占用前 20 的线程及其所属进程名和父进程
-
pidstat -t -p
1 :持续监控某进程的各线程 CPU 使用变化,适合抓瞬时峰值
特别注意 comm 列显示的是线程名(如 java、ksoftirqd/0、mysqld),而非完整命令行,有助于识别内核线程或 JVM 内部线程。
区分应用逻辑问题与系统环境问题
定位到具体进程后,进一步判断根因类型:
-
Java 进程:用 jstack
查看线程栈,重点关注 RUNNABLE 状态且堆栈停留在业务方法或正则匹配、JSON 解析等 CPU 密集处;配合 jstat -gc 排查是否频繁 GC 导致 CPU 暴涨 - MySQL:执行 SHOW PROCESSLIST,找 State = Sending data / Sorting result / Copying to tmp table 且 Time 很长的查询;检查慢日志和执行计划
- 内核线程(如 ksoftirqd、kworker)持续高占用:可能是网卡软中断不均衡(多队列未开启或 RPS/RFS 未配置)、存储驱动异常、或硬件故障(如坏盘引发大量重试)
-
strace -cp
可统计该进程系统调用耗时分布,若 epoll_wait、read、write 占比异常低而 nanosleep 高,可能程序逻辑空转
临时缓解与长期规避建议
应急时可限制问题进程资源,避免影响其他服务:
- 用 cputool 或 cpulimit -p
-l 50 临时限制其最多使用 50% CPU - 对容器环境,通过 docker update --cpus=1.5
或 cgroups v2 的 cpu.max 限频 - 长期需补充监控:部署 node_exporter + Prometheus,采集 per-CPU、per-thread、interrupts、softirqs 指标;对 Java 应用集成 JMX Exporter
- 避免在生产环境运行无超时、无并发控制的脚本(如 while true; do curl ...; done),应加入 sleep、失败退避、最大重试次数等防护










