🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,
15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea


Java 应用程序CPU 100%问题排查优化实战
今天再给大家讲一个 CPU 100% 优化排查实战。
收到运维同学的报警,说某些服务器负载非常高,让我们开发定位问题。拿到问题后先去服务器上看了看,发现运行的只有我们的 Java 应用程序。于是先用 ps 命令拿到了应用的 PID。
ps:查看进程的命令;PID:进程 ID。
ps -ef | grep java可以查看所有的 Java 进程。前面也曾讲过。
接着使用 top -Hp pid 将这个进程的线程显示出来。输入大写 P 可以将线程按照 CPU 使用比例排序,于是得到以下结果。

果然,某些线程的 CPU 使用率非常高,99.9% 可不是非常高嘛()。
为了方便问题定位,我立马使用 jstack pid > pid.log 将线程栈 dump 到日志文件中。关于 jstack 命令,我们前面刚刚讲过。
我在上面 99.9% 的线程中随机选了一个 pid=194283 的,转换为 16 进制(2f6eb)后在线程快照中查询:

线程快照中线程 ID 都是16进制的。
发现这是 Disruptor 的一个堆栈,好家伙,这不前面刚遇到过嘛,老熟人啊, 强如 Disruptor 也发生内存溢出?
真没想到,再来一次!
为了更加直观的查看线程的状态,我将快照信息上传到了专门的分析平台上:http://fastthread.io/,估计有球友用过。

其中有一项展示了所有消耗 CPU 的线程,我仔细看了下,发现几乎都和上面的堆栈一样。
也就是说,都是 Disruptor 队列的堆栈,都在执行 java.lang.Thread.yield。
众所周知,yield 方法会暗示当前线程让出 CPU 资源,让其他线程来竞争(多线程的时候我们讲过 yield,相信大家还有印象)。
根据刚才的线程快照发现,处于 RUNNABLE 状态并且都在执行 yield 的线程大概有 30几个。
初步判断,大量线程执行 yield 之后,在互相竞争导致 CPU 使用率增高,通过对堆栈的分析可以发现,确实和 Disruptor 有关。
好家伙,又是它。
既然如此,我们来大致看一下 Disruptor 的使用方式吧。看有多少球友使用过。
第一步,在 pom.xml 文件中引入 Disruptor 的依赖:
<dependency>
<groupId>com.lmax</groupId>


![表情[baoquan]-拾光赋](https://blogs.ink/wp-content/themes/zibll/img/smilies/baoquan.gif)


暂无评论内容