zoukankan      html  css  js  c++  java
  • 空循环导致CPU使用率很高

    业务背景

      业务背景就是需要将多张业务表中的数据增量同步到一张大宽表中,后台系统基于这张大宽表开展业务,所以就开发了一个数据同步工具,由中间件采集binlog消息到kafka里,然后我去消费,实现增量同步。

    生产环境发现的现象  

      在程序发布到生产环境时候,机器的CPU使用率立马被打到100%, load还在不停的上升,开始机器的配置是4核心8G内存,load可以到21,通过topc命令查看load average的三个值都大于20,说明机器非常的繁忙。

    排查步骤及手段

      1.  通过top命令查看到CPU使用率达到100%,但是内存却没有多大变化,内存变化可以通过gc日志可以观察的到。这时候配置文件中配置的是40个线程处理数据增量同步任务

      2. 当时怀疑是不是线程数配置的多了原因导致的,所以将线程数调至为20个,但发现CPU依然是高位运行

      3. 由于是生产环境,当时运维直接就建议升级服务器配置,有4核心8G内存升级到8核心8G内存。但是将程序部署到新服务器上后,新服务器的CPU使用率依然是100%,load也能达到20

      4. 进一步将线程数调至为10个,CPU依然高位运行

      5. 这是我就怀疑代码出问题了,top -Hp pid命令查看是那些线程最耗CPU,这里发现了一个奇怪的现象是:最耗CPU的线程数刚好10个,跟配置文件中配置的个数一样

      6. 使用jstack命令查看thread dump日志,发现就是自己配置的10个线程的状态为Runnable,表示一直在那里运行。

    排查到步骤6时,再结合第5点诡异的现象,回头再去看代码,在一个while(true)循环里不停的从队列中取数据,取到了则insert或update宽表, 取不到则立马进入下一轮循环,中间没有任何的sleep,导致系统会不停的调度该线程,占用CPU时间片,导致系统load飙升。

    解决方法

      在while(true)中如果从队列中取不到数据则sleep(1000), 加上这行代码之后,可以很明显的看到服务器的load在下降,知道下降到一个很低的值,因为这台机器的配置很高,只开了10个线程处理任务,负载当然很低。

    空循环会导致CPU使用率很高

      Linux系统中线程有几种状态:就绪状态,运行状态,阻塞状态,挂起状态,僵死状态。 Linux进程线程调度是对就绪队列中的线程进行时间片分配,阻塞状态和挂起都在阻塞队列中,只有唤醒之后才会被加入到就绪队列中等待内核的调度。

      空循环虽然什么都没有做,也没有任何的阻塞条件(如sleep),进程一直处于运行状态,即使时间片一到被切换了,但是改进程还是处于就绪状态,等待下次调度。Linux内核调度是很复杂的,除了时间片之外还有优先级的权重,对于一直处于优先级的线程优先级会提高,这样空循环所在的线程分配的时间片的比重就会增多,导致系统负载上升。

      至于空循环是如何影响CPU使用率和负载的,可以参考这边文章:https://www.2cto.com/kf/201601/488270.html

      

     

      

     

  • 相关阅读:
    抽卡 状压DP+期望DP+系数递推
    20190903考试反思
    20190823考试反思
    约瑟夫类问题研究
    树位DP
    20190823考试反思
    20190820考试反思
    20190818考试反思
    20190817考试反思
    PowerBuilder--Aes128加解密
  • 原文地址:https://www.cnblogs.com/jsnr-tdyd/p/8782338.html
Copyright © 2011-2022 走看看