0. 引言

前一段时间出现了一个正则表达式引起的线上CPU爆满的问题,一开始没有在第一时间定位到问题,这里也特此记录一下,同时也系统的梳理下CPU爆满问题的排查思路和方法,为后续的同学提供参考。

1. CPU爆满问题产生的原因

我们首先要理解cpu飙升爆满的原因,才能正确的进行排查:

  • 并发量提升:这类是比较容易产生的原因,也就是突然之前提升上来的并发量,导致线上服务器资源不足,cpu占用居高不下。
  • 功能耗费计算资源:这类原因我们也称为计算密集型任务,也就是比较耗费计算资源的功能,比如负责的数据处理、图片处理、加密等
  • 循环递归:这类是在开发时不规范的书写导致,比如写了一个死循环、或者较深的递归调用,导致资源一直消耗,无法释放线程
  • 资源竞争:在多个线程或进程之前产生了对同一资源的竞争调用,比如锁竞争,连接池竞争等
  • 服务故障:因为第三方组件故障导致的cpu占用过高,这类问题发生的概率较小,因为一般生产环境会部署监控服务,组件故障一般会第一时间预警出来
  • 硬件故障:因为cpu本身硬件故障导致的占用飙升

以上这些原因中,真正在我们软件生产中容易产生的就是并发量提升、功能耗费计算资源、循环递归、资源竞争其他情况其实相对较少,或者其他情况出现故障时,已经不再是开发者能够介入的范围了。所以今天我们主要针对这4种原因来进行讲解

2. 解决思路

  • 并发量提升:

首先针对这个原因导致的CPU飙升,本身不在代码层,而在于架构层上,既然并发量提高,那么紧急提升服务器资源或对并发进行限流是比较好的措施

  • 功能耗费计算资源:

这类问题导致的CPU飙升主要有两种处理思路,一是先定位到是哪个功能占用的cpu资源居高不小,如何定位我们将在下面讲解;然后考量这个功能本身能不能优化,是否真的需要占用这么多资源;如果本身确实是计算非常复杂,那么就要考虑增加服务器资源

  • 循环递归:

死循环和过深递归这是我们明确要避免的,但如何定位到是难点,这也是我们将在下面讲解的。定位到后,就要进行代码优化,避免此种情况

  • 资源竞争:

资源竞争这类的要根据实际占用的什么资源来分析,比如是锁竞争,那么应当就采取避免竞争的措施,比如减少锁的使用、使用乐观锁、使用JUC同步组件等

3. 定位CPU爆满问题

首先要定位CPU爆满问题,其实核心就是要定位占用CPU高的线程,以及对应的代码。和OOM问题一样,在定位到代码位置后,问题的解决就好操作了

这里为了让大家感受到实际的排查操作,我模拟一个会导致CPU飙升的代码,运行后我们来一起排查。如果后续大家想要跟练的,可以在下述git下载源码:

https://gitee.com/wuhanxue/wu_study/tree/master/demo/cpu_oom_demo

1、运行项目

 java -jar cpu_oom_demo-0.0.1-SNAPSHOT.jar

2、调用会造成cpu飙升的接口,模拟cpu爆满

http://192.168.244.14:8080/cpu/build?time=-1

3、top指令观察进程资源占用情况

如果你的服务器是多核的,要注意承上核数才是最大占用率。比如4核处理器,CPU最大能到400%,如果当前占用还只是100%,说明还远没有达到极限

这里我是运行在单核虚拟机上的,所以cpu占用率最高是100%,可以看到已经飙升到99%了。可以看到占用CPU占用最高的进程的pid是2127

2、如果一台服务器上部署了多个java程序的,可以通过jinfo指令或者jps指令确认进程ID对应的服务名

jps -l

3、我们用top -Hp查看该进程下的线程资源占用情况

top -Hp 2127

查看到CPU占用最高的的线程的pid是2140,第二是2141

4、我们继续查看该线程下的堆栈日志信息,这一步可以通过jstack指令实现,但是该工具打印的日志中的线程ID都是16进制的,所以我们需要将线程id转换为16进制

两种方式实现10转16进制:

  • 在线查询:https://jisuan5.com/decimal-to-hexadecimal/

  • linux指令转换
printf '%x\n' 2140

在使用jstack工具之前,我们先了解一下他的参数:

jstack [options] 进程pid
options参数值:
-F: 强制打印一个堆栈转储
-l:打印关于锁的其他信息
-m: 打印包含java和本地方法栈的堆栈信息
-h: 打印帮助信息

直接执行jstack 2127打印进程信息发现信息实在太多,很难捕捉到自己先要的信息

所以我们根据线程id过滤一下,查看cpu占用最大的线程的堆栈信息,其中grep -A 50表示指定关键字的后面50行日志

 jstack 2127 | grep -A 50 85c

从上述的日志信息我们可以看出,问题出在正则表达式的调用上,同时方法定位到是cpuBuild方法,那么自此,我们就可以去代码位置进行调整了


通过本地测试,可以知道,原因就是原来书写的正则表达式占用了过多的cpu,在判定长字符串时,耗时较长,线程一直得不到释放,导致cpu居高不下

当然可以看到我们这里书写了一个死循环,目的是为了简单的模拟用户的高并发请求,如果不想书写死循环的,也可以用jmeter来做并发调用,同样可以模拟出cpu爆满的效果

我们也可以通过Thread关键字来查询线程数量,实现并发量的统计

jstack -l 2127 | grep 'java.lang.Thread.State' | wc -l


如果想要将堆栈信息导出到文件中查看的,也可以通过jstack指令实现

jstack 2127 > 2127.log

而针对这类CPU问题的解决,我们定位到问题代码后,就要靠大家针对代码进行优化了

总结

综上,就是我们通过jstack工具和其他指令,来定位CPU飙升问题的思路和步骤,希望可以给大家在实际生产中提供到帮助

JVM:线上服务CPU爆满,如何排查(三)相关推荐

  1. java - JVM 线上服务的FGC问题排查

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  2. JVM:线上服务的FGC问题排查

    原文链接:https://blog.csdn.net/bestxianfeng163/article/details/107972060 线上服务的GC问题,是Java程序非常典型的一类问题,非常考验 ...

  3. 线上服务的FGC问题排查,看这篇就够了!

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  4. 【转】线上服务的FGC问题排查,看这篇就够了!

    线上服务的GC问题,是Java程序非常典型的一类问题,非常考验工程师排查问题的能力.同时,几乎是面试必考题,但是能真正答好此题的人并不多,要么原理没吃透,要么缺乏实战经验. 过去半年时间里,我们的广告 ...

  5. 线上服务 CPU 又 100% 啦?一键定位 so easy!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:my.oschina.net/leejun2005/blog ...

  6. 线上服务 CPU 100%?一键定位 so easy!

    0.背景 经常做后端服务开发的同学,或多或少都遇到过 CPU 负载特别高的问题.尤其是在周末或大半夜,突然群里有人反馈线上机器负载特别高,不熟悉定位流程和思路的同学可能登上服务器一通手忙脚乱,定位过程 ...

  7. 线上服务 CPU 100% ?一键定位 so easy!

    点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 A man should have one dream at le ...

  8. 一键定位java 线上服务 CPU 100%

    传统方法: top oder by with P:1040 // 首先按进程负载排序找到 axLoad(pid) top -Hp 进程PID:1073 // 找到相关负载 线程PID printf & ...

  9. 面试官:线上服务CPU飙高怎么排查?

    用jstack排查 先执行top,找到CPU占用比较高的进程 jstack 进程id > show.txt 找到进程中CPU占用比较高的线程,线程id转为16进制 到show.txt文件中根据线 ...

最新文章

  1. JDK1.8源码(六)——java.util.LinkedList 类
  2. 情人节来了!没有50W彩礼,女朋友被强行拖走。。。
  3. 记录最近的一些遇到的前端面试题
  4. django:bootstrap table加载django返回的数据
  5. python中if嵌套语句的作用_讲解Python中if语句的嵌套用法
  6. React之初始化state
  7. 字段与属性 c# 1613532992
  8. 美团搜索推荐多业务商品排序探索与实践
  9. Android Studio(九):引用jar及so文件
  10. java中常用的算法--URL
  11. 网络云盘项目——总体介绍、附源码链接
  12. aamp;m大学计算机科学,斑马博士捷报|德克萨斯AM大学 (TAMU) MSc Computer Science录取!...
  13. 新浪微博热门话题 (30 分)
  14. 除了攀附名人、杜撰荣恩录,家谱造假中,还有这件事令人羞耻
  15. (上)苹果有开源,但又怎样呢?
  16. 基于java的高校运动会管理系统的设计与实现--毕业论文(可仅作参考)
  17. NVIDIA NCCL 源码学习(五)- 路径计算
  18. 判断两个圆相切或相交
  19. 性能测试专项:帧率测试 FPS
  20. android+1024*768分辨率什么意思,网站上提示的建议用1024X768分辨率,是什么意思?...

热门文章

  1. 【新春特辑】基于文心大模型的新年春联生成器
  2. SAR信号处理基础——脉冲压缩/匹配滤波
  3. 光伏太阳能直流浪涌保护器应用方案
  4. Gmapping的个人理解
  5. Tensorflow-gpu+Cuda+cuDNN安装(详细且包含失败解决教程)
  6. 【路径规划】局部路径规划算法——DWA算法(动态窗口法)|(含python实现 | c++实现)
  7. 第一章 BIRT简介
  8. 全球及中国汽车座椅加热行业现状分析及前景发展规划研究报告2021年版
  9. C++基础入门(上):命名空间、输入输出、缺省参数
  10. 《涨知识啦32》-SBD器件中的肖特基二极管漏电流机制 (上)