CPU load高但CPU usage低问题排查

讲故事

最近服务总是出现 高的告警,且告警经常还出现在低峰期的凌晨,所以很明显不是用户流量导致的负载高,但是 却很低。查看内存使用情况: 接近100%,查看磁盘情况:周期性(30分钟左右)的较高, 低,但是 (平均请求队列的长度)周期性(30分钟左右)的较高,且和 高 同频。 后续经排查机器上上 ,查看周期为30分钟的定时任务,发现定时任务为 ,并查看该定时任务的日志里的执行时间和 高也对得上。因此以上很多现象同频共振,我们只能说明这些现象具有强相关性,就像“啤酒和尿布的故事“,但是具体的逻辑归因链是怎样的上的每一个环节都需要证据支撑。

结论

分析问题

我们的机器内存8G。JVM 参数:

  1. 问题一:为什么 一直平稳接近8Gjvm 定义6G才使用一半,不可能打满8G/strong>。看统计方式的公式可知,只要jvm不向操作系统释放内存, 和的大小就不会变化。jvm的GC只是逻辑释放内存,但依然被jvm所管理,并不是物理释放(所以top查看该Java进程RES列使用内存6G左右)。所以像指标才会敏感的跟踪GC带来的jvm内存变化。从操作系统的层面来说是已经接近使用6G了。
  2. 问题二:为什么内存使用如此高导致使用了swap分区/strong>

申请机器时预选中安装了tomcat(事实上不需要),导致服务部署后,机器上起了两个Java进程,其中一个是tomcat启动的,通过下面命令观察到其内存使用量1.5G左右。

随着业务服务JVM内存向操作系统申请的内存越来越多,可以通过top命令看到RES列逐渐变大至接近6G。总体内存占用 = JVM1(6G) + JVM2(tomcat 1.5G)+ 非JVM内存。导致OS最终可用内存不足,进而使用到swap分区

  1. 问题三:为什么 高而
    等待磁盘I/O完成的进程过多,导致进程队列长度过大,但是cpu运行的进程却很少,这样就体现到负载过大了,cpu使用率低。
  2. 问题四: 为什么磁盘请求队列排队较多 会导致 高/strong>

uptime和top等命令都可以看到load average指标,从左至右三个数字分别表示1分钟、5分钟、15分钟的load average:

  • 如果平均值为 0.0,意味着系统处于空闲状态
  • 如果 1min 平均值高于 5min 或 15min 平均值,则负载正在增加
  • 如果 1min 平均值低于 5min 或 15min 平均值,则负载正在减少
  • 如果它们高于系统 CPU 的数量,那么系统很可能会遇到性能问题(视情况而定)

在 Linux 中,对于整个系统而言,load averages 是 “system load averages”,测量正在运行和等待运行的线程数(CPU,磁盘,不间断锁),包括uninterruptible sleep的进程数量。不像其他操作系统的 的定义,Linux里衡量的不仅仅是CPU资源的负载了。优点:包含了对不同资源的需求。

当看到load average很高的时候,你不知道是runnable进程太多还是uninterruptible sleep进程太多,也就无法判断是CPU不够用还是IO设备有瓶颈。

进程在cpu上面运行需要访问磁盘文件,这个时候cpu会向内核发起调用文件的请求,让内核通过DMA方式去磁盘取文件,这个时候会切换到其他进程或者空闲,这个任务就会转换为uninterruptible sleep状态。当这种读写请求过多就会导致uninterruptible sleep状态的进程过多,从而导致负载高,cpu低的情况。

sched/loadavg.h:

sched/loadavg.c

is the kernel timer frequency, which is defined when compiling the kernel. On my system, it’s :

解决问题

  1. 去掉预安装的tomcat软件
  2. 减少JVM配置的最大堆使用

问题得以解决。

参考资料:

  1. Linux Load Averages:什么是平均负载/li>
  2. High load average but low CPU usage and disk I/O

附录:

top命令:

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91960 人正在系统学习中

来源:研发之道

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年9月16日
下一篇 2020年9月16日

相关推荐