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

news2025/1/23 22:34:24

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飙升问题的思路和步骤,希望可以给大家在实际生产中提供到帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

八大排序算法之插入排序、希尔排序、选择排序

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【数据结构初阶(C实现)】 本篇主要讲解八大排序算法中的三种排序,分别是:插入排序、希尔排…

yum源配置

一、互联网yum源(centos7为例): cd /etc/yum.repos.d/ && rm -f *.repo;wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo…

Golang编译报错 ‘invalid char’

现象 最近在新电脑安装go环境,发现 golang 包名如果有汉字就不能编译运行。 具体来讲,就是 go mod tidy 报错 ‘invalid char’ 但是,我在以前的电脑上运行 go mod tidy 没有问题 原因 我对比了 go sdk 版本,旧电脑用 go 1.13…

Html5钢琴块游戏制作(音乐游戏)

当年一款手机节奏音游,相信不少人都玩过或见过。最近也是将其做了出来分享给大家。 游戏的基本玩法:点击下落的黑色方块,弹奏音乐。(下落的速度会越来越快) 可以进行试玩,手机玩起来效果会更好些。 点击…

Java就业前景如何?

Java还有出路吗?2023年的就业市场依然经历着面临挑战,很多有经验有技术的人被淘汰下来,而马上又有一千多万的新鲜血液涌入就业市场。经济大环境对于各行各业的影响是非常大的,也为IT行业的内卷推波助澜。在2023年想学习Java入行就…

面试造航母,入职拧螺丝,工资...

有粉丝跟我吐槽说:金三银四去面试软件测试岗,真的是面试造航母,入职拧螺丝,工资还低 这种现象很正常,因为找一个测试员,当然希望他能做的业务越多越好,最好像机器猫一样,啥事儿都能…

Chatgpt 实践经验分享

数据准备:ChatGPT 需要大量的训练数据来支撑模型的训练和优化,因此需要进行充分的数据准备。在数据准备方面,需要考虑数据的质量、覆盖范围以及数据的预处理方式等。模型训练:ChatGPT 使用端到端学习的方式训练模型,需…

自动控制原理模拟卷1

自动控制原理模拟题一 Question1 已知机械系统和电网络如下图所示,求解两个系统的传递函数,并证明这两个系统是相似系统. 解: 【图a系统】 由电网络原理图并根据复阻抗原理,可得系统传递函数为: E o ( s ) E i

离线安装k8s/kubernetesv1.17.1

条件: 3台没有网络的centos7.9服务器 1.系统优化 hostnamectl set-hostname k8s-master && bash #只在master节点上执行 hostnamectl set-hostname k8s-node1 && bash #只在node1节点上执行 hostnamectl set-hostname k8s-node2 && …

基于stm32单片机和rt-thread操作系统的智能灯

目 录 一、 总体概况 二、 各部分介绍 2.1 STM32F4开发板 2.2 光敏模块 2.3 麦克风模块 2.4 超声波模块 三、 RT-Thread介绍 四、 开发过程 五、 未来设想 六、 开发心得 总体概况 本次测试技术与信号处理课程作业,我利用了stm32单片机和rt-thread…

SpringBoot中使用WebSocket Demo

大概目录结构 依赖只引入了JSP 和SpringBoot整合WebSocket Spring Web index.jsp <% page contentType"text/html;charsetUTF-8" language"java" %> <!DOCTYPE html> <html> <head><meta charset"utf-8"><s…

STM32开发(十三)STM32F103 片内资源 —— 外部中断 按键 详解

文章目录一、基础知识点二、开发环境三、STM32CubeMX相关配置四、Vscode代码讲解五、结果演示一、基础知识点 外部中断/事件控制器主要特征&#xff1a; 每个中断/事件都有独立的触发和屏蔽每个中断线都有专用的状态位支持多达20个软件的中断/事件请求检测脉冲宽度低于APB2时…

校园一键报警柱的作用

校园一键报警柱是一种用于校园安全的紧急报警系统&#xff0c;可以随时随地向校园安全管理部门发送紧急警报。这种系统通常采用带有紧急按钮的电缆或无线警报装置&#xff0c;使学生、教师和工作人员可以在出现紧急情况时轻松报告安全问题&#xff0c;迅速地通知校园安全人员&a…

彻底理解java中泛型

一、什么是泛型&#xff1f; 泛型是JDK5引入的一种特性&#xff0c;是一种类型安全检测机制&#xff0c;开发者在编译阶段发现类型相关的报错。 泛型即参数类型化&#xff0c;将操作的数据类型定义为参数&#xff0c;可定义在类、接口、方法中。 可以把类型参数看作是使用参数化…

CorelDRAW2023中文版矢量制图及设计软件更新发布

矢量制图及设计软件&#xff0c;CorelDRAW Graphics Suite 2023中文版&#xff08;以下简称CorelDRAW 2023&#xff09;对新手来说&#xff0c;对于自己多久才能学会cdr软件这个问题是比较关心的。如果你的学习能力比较强&#xff0c;一周时间是有可能完全学会cdr的。但由于每个…

您可以找到的 5 种最佳数据恢复软件

数据恢复软件对很多人来说是一个非常有价值的工具。无论您是否意识到&#xff0c;宝贵的数据都有被删除的风险&#xff0c;而且很多人直到丢失数据才知道数据的价值。 5 种数据恢复软件 如果发生这种情况&#xff0c;您需要最好的软件来恢复数据并确保这种情况不会再次发生。这…

PostgreSQL 函数(一) 数学函数和字符串函数

1.数学函数 1.1.符号函数sign 用于判断正负 1.2.求余函数mod 1.3.圆周率函数pi 1.4.平方根函数sqrt 1.5.向上取整函数ceil和ceiling 1.6.向下取整函数floor 1.7.绝对值函数abs 1.8.四舍五入函数round 第2位参数为保留位数 1.9.其他函数 正弦函数sin, 反正弦函数asin, 余弦…

考研复试确认神操作!

终于进行到了研究生考试的尾声&#xff0c;但让考生感到无力吐槽的事情&#xff0c;却还在继续上演&#xff0c;比如苏科大&#xff0c;再比如中地大、苏大&#xff0c;三所学校的神操作&#xff0c;着实让无数考生忍不住调侃&#xff1a;原来考研不仅拼实力&#xff0c;还得拼…

类ChatGPT代码级解读:如何从零起步实现Transformer、llama/ChatGLM

前言 最近一直在做类ChatGPT项目的部署 微调&#xff0c;关注比较多的是两个&#xff1a;一个LLaMA&#xff0c;一个ChatGLM&#xff0c;会发现有不少模型是基于这两个模型去做微调的&#xff0c;说到微调&#xff0c;那具体怎么微调呢&#xff0c;因此又详细了解了一下微调代…

欧拉回路问题

文章目录 欧拉回路程序设计程序分析欧拉回路 有一条名为Pregel的河流经过Konigsberg城。城中有7座桥,把河中的两个岛与河岸连接起来。当地居民热衷于一个难题:是否存在一条路线,可以不重复地走遍7座桥。这就是著名的七桥问题。它由大数学家欧拉首先提出,并给出了完美的解答…