Linux CPU 使用率 100% 问题分析

7次阅读

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

Linux CPU 使用率 100% 问题分析

Linux 系统 CPU 使用率长期维持在 100%,通常不是“CPU 不够用”这么简单,而是某个或某几个进程、线程异常占满资源,或内核层面存在调度、锁、中断等瓶颈。快速定位关键线索比盲目重启更有效。

确认是用户态还是内核态耗尽 CPU

运行 tophtop,观察顶部的 %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 列显示的是线程名(如 javaksoftirqd/0mysqld),而非完整命令行,有助于识别内核线程或 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_waitreadwrite 占比异常低而 nanosleep 高,可能程序逻辑空转

临时缓解与长期规避建议

应急时可限制问题进程资源,避免影响其他服务:

  • cputoolcpulimit -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、失败退避、最大重试次数等防护
text=ZqhQzanResources