记录一次线上服务CPU飙高问题
2023.07.20 20:01:38线上一个服务发生了CPU过高的告警,

看告警信息当前的CPU使用率已经达到了82.65%,问题已经很严重,赶紧开始排查起来。来复盘下如何排查这类问题,
一、排查方法
1、找到cpu过高的进程ID
收到告警后,第一件事要做的就是找到CPU过高的程序的线程id(pid),可以使用jps或ps -ef |grep java两个命令均可,
1.1、jps
使用jps命令
jps
得到下面的结果

也就是进程ID是6。
再看使用ps的结果
1.2、ps
使用ps命令
ps -ef |grep java
得到下面的结果

可以看到进程ID也是6。
当然除了上面两个命令,还可以使用top,也可以很快找到CPU过高的服务进程ID。
我们已经知道了cpu过高的服务进程ID是6,但仅知道进程ID是无用的,需要进一步知道这个进程中哪些线程占用CPU过高。
2、找到cpu过高的线程ID
这里使用的是top命令
top -Hp 6
得到的结果如下

可以看到线程1110 1125 1112 1121等占用CPU过高,基本都在80%,基本可以断定就是这些线程在占用CPU。
找到占用CPU过高的线程后,就要看下相应的堆栈信息。
1.3、打印进程堆栈
使用jstack命令,jstack命令可以打印出进程的堆栈,通过堆栈信息可以分析到线程的执行情况,
jstack -l 6
可以看到很多类似这样的信息,这些信息中有一个很重要的那就是nid=0x11,这个是代表的线程ID,聪明的你也一定知道这里是16进制,和刚才使用top -Hp命令看到的不一样,那里是10进制的。

为了找到线程占用cpu过高的堆栈,需要把线程ID做一次进制转换,既由10进制转换为16进制,
例,1110--》0x456 1125--》0x465
以0x465为例,在堆栈中查找相应的线程堆栈,
1.4、查找线程堆栈
使用0x465查找其对应的线程堆栈

可以看到线程0x465的线程状态是RUNNABLE,而且看到了很多正则的调用,继续往下看,找到了调用的代码,

最后分析是由于死循环引起的线程占用CPU过高。
上面是我把文件下载下来进行的查找,那如何生成堆栈文件,可以使用下面的命令
jstack -l 6 > dump.txt
生成后下载到本地即可。
如果线上环境无法下载,则只能通过命令进行查找
jstack -l 6 | grep -A 10 0x465
这样便可以看到相应的内容了。
二、fastthread
有没有觉得使用jstack命令导出文件后自己分析很麻烦,没事有工具,可以使用fastthread。
其网址是:https://fastthread.io/
将jstack或者其他工具dump的堆栈文件上传到该网站同样可以分析出结果。

将刚才的文件上传后,得到分析报告,由于是分析CPU过高,重点看cpu threads即可。

可以看到nativeId:1125即对应top -Hp出的线程ID,这里fastThread已经进行了进制转换,无需手动操作了,很贴心。点击查看完整的堆栈信息即可分析出相应的问题。
三、总结
一般程序CPU过高,大多数和死循环有关,分析此类问题的一般步骤是,
1、使用jps/ps -ef |grep java/top等命令找到进程ID,即pid;
2、使用top -Hp pid 找到进程中占用CUP的线程ID;
3、使用jstack打印堆栈;
4、使用线程ID在堆栈中找到对应的线程堆栈;
5、分析线程堆栈,找到问题;
参考:
(7条消息) jstack命令解析_fightingD&W的博客-CSDN博客
Linux命令之Grep——文本搜索 - 阅读清单 - 腾讯云开发者社区-腾讯云 (tencent.com)
推荐阅读
花了半天时间,使用spring-boot实现动态数据源,切换自如

记录一次线上服务CPU飙高问题的更多相关文章
- Linux(2)---记录一次线上服务 CPU 100%的排查过程
Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...
- 记一次线上服务CPU 100%的处理过程
告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...
- 线上服务器CPU彪高的调试方式
原文内容来自于LZ(楼主)的印象笔记,如出现排版异常或图片丢失等问题,可查看当前链接:https://app.yinxiang.com/shard/s17/nl/19391737/2fee7b91-f ...
- 线上服务 CPU 100%?一键定位 so easy!
转自: https://my.oschina.net/leejun2005/blog/1524687 摘要: 本文主要针对 Java 服务而言 0.背景 经常做后端服务开发的同学,或多或少都 ...
- 线上服务CPU100%问题快速定位实战
功能问题,通过日志,单步调试相对比较好定位. 性能问题,例如线上服务器CPU100%,如何找到相关服务,如何定位问题代码,更考验技术人的功底. 58到家架构部,运维部,58速运技术部联合进行了一次线上 ...
- 线上服务CPU100%问题快速定位实战--转
来自微信公众号 架构师之路 功能问题,通过日志,单步调试相对比较好定位. 性能问题,例如线上服务器CPU100%,如何找到相关服务,如何定位问题代码,更考验技术人的功底. 58到家架构部,运维部,58 ...
- java进程CPU飙高
因为这段时间一直在弄监控,但是工作还是在进行中 因为机器不多,所以今天早上巡检了一下,看到一台生产机器上的CPU飙高 top
- 你要偷偷学会排查线上CPU飙高的问题,然后惊艳所有人!
GitHub 20k Star 的Java工程师成神之路,不来了解一下吗! GitHub 20k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 20k Star 的Java工 ...
- 一次线上服务高 CPU 占用优化实践 (转)
线上有一个非常繁忙的服务的 JVM 进程 CPU 经常跑到 100% 以上,下面写了一下排查的过程.通过阅读这篇文章你会了解到下面这些知识. Java 程序 CPU 占用高的排查思路 可能造成线上服务 ...
- 线上服务内存OOM问题定位[转自58沈剑]
相信大家都有感触,线上服务内存OOM的问题,是最难定位的问题,不过归根结底,最常见的原因: 本身资源不够 申请的太多 资源耗尽 58到家架构部,运维部,58速运技术部联合进行了一次线上服务内存OOM问 ...
随机推荐
- Java线程中断机制
在阅读AQS源码以及juc包很多基于AQS的应用源码过程中,会遇到很多interrupted相关的方法,这里复习一下java线程中断相关. 要点:使用interrupt()中断一个线程,该方法只是标记 ...
- 绝对强大的三大linux指令:ar, nm, objdump
前言 如果普通编程不需要了解这些东西,如果想精确控制你的对象文件的格式或者你想查看一下文件对象里的内容以便作出某种判断,刚你可以看一下下面的工具:objdump, nm, ar.当然,本文不可能非常详 ...
- 性能_2 Jmeter脚本增强
一.写脚本注意事项(回顾): 协议: http,https必须写 域名或ip: 不能有/ 请求方法: 看清楚接口文档 路径: 不要把 域名和ip再次 路径中,前后空格要看清楚 %20 空格的urlen ...
- docker(一):Develop faster. Run anywhere.
前言 在进行微服务部署时,首先需要进行部署环境的搭建.目前,Docker 已经成为了微服务部署的主流解决方案之一.Docker 可以帮助我们更快地打包.测试以及部署应用程序,从而缩短从编写到部署运行代 ...
- 2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数?
2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数? 答案2022-07-09: 方法一:递归,要i还是不要i. 方法二:动态规划.需要两张dp表. 代码用rus ...
- 2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。 返回将数组分隔变换后能够得到的元
2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组.分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值. 返回将数组分隔变换后能够得到的元 ...
- JDBC-Utils层的简单运用
项目中JDBC的Utils层运行需要以下六个步骤 //1.定义属性为空 private static String driver = null; private static String url = ...
- 使用taro+canvas实现微信小程序的图片分享功能
业务场景 二轮充电业务中,用户充电完成后在订单详情页展示订单相关信息,用户点击分享按钮唤起微信小程序分享菜单,将生成的图片海报分享给微信好友或者下载到本地,好友可通过扫描海报中的二维码加群领取优惠. ...
- 【工作随手记】mysql优化之1
原SQL: SELECT p.id, p.NAME, p.idcard, p.phone, p.plate, p.FAMILY_NO FROM t_person_info p WHERE p.id I ...
- C#中BitConverter.ToUInt16、BitConverter.ToUInt32原理与用法详解
一.基础知识 a.1字节=8位(1Byte=8bit) 二进制表示:11111111 十进制表示:255 计算机内部约定用多少字节来规范数值,比如红绿蓝三色在计算机中只分配了一个字节,一个字节 ...