记一次CPU飙升BUG

发表于:2019-6-24 21:30

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:hdqdon    来源:码上升华

  一.前言
  上线后,CPU飙升到100%,怎么办?马上重启?大错特错,马上重启只会让这个雷石沉大海,治标不不治本,等待你的下次的历史重演!
  二.现象
  监控告警,某机器的CPU飙升到100%
  三.分析
  第一步,通过以下指令找到CPU高的进程号
  top -p `pgrep -d , java`
  第二步,通过以下指令找到CPU高的线程号
  top -Hp 进程号
  第三步,通过以下指令把线程号转换成16进制
  printf"%x\n" 线程号
  第四步,通过以下指令打印线程的stacktrace
  jstack 进程号 |grep 16进制线程号 -A 50
  第五步,分析stacktrace的信息,定位哪个地方导致的CPU占用率高,以下是我曾经遇到过一个真实案例的截图
  第六步,从上面的截图可以可以定位到了FundClearRecordCtrl这个类里面的存在HashMap使用不当,导致死循环引发的CPU飙升
  1、正常情况下
  2、线程不安全,多线程并发的情况下,假如两个线程T1和T2,会造成e1.next = e2,而e2.next = e1,即形成环形,会导致死锁,然后现象就是CPU飙升
  排查方向基本明朗,接下来让我们回到具体问题中,来解决问题!
  四.解决
  HashMap线程不安全,对于久经沙场的小伙伴们来说,这种认知还是有的,但是为啥还会入坑呢?
  这个类没有明显的把HashMap作为公共变量,应该不存在多线程去操作HashMap的情况呀?
  不能怪小伙伴,这个bug还真不好找,隐藏得有点深!
  小伙伴也是无意中踩了坑,为什么说这个BUG隐藏得深呢?
  由于DB资源紧缺,为了减少DB的直接操作,在DBUtil加了缓存,小伙伴在调用DBUtil的情况下,拿到的缓存的HashMap,此时该HashMap就是一个公共资源了,对于线程不安全的HashMap在多线程并发的情况下,理所当然的就进入了死循环!
  五.总结
  1、遇到CPU飙升,第一时间不好重启,先找到CPU高的类,确定好排查方向;
  2、HashMap线程不安全,多线程并发场景下建议使用ConcurrentHashMap;

     上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号