今天测试团队反馈说,服务A的响应很慢,我在想,测试环境也会慢?于是我自己用postman请求了一下接口,真的很慢,竟然要2s左右,正常就50ms左右的。

于是去测试服务器看了一下,发现服务器负载很高,并且该服务A占了很高的cpu。先用top命令,看了load average,发现都到了1.5左右(双核cpu)了,并且有一个java进程(20798)占用cpu一直很高,如下图:

于是,用命令jps -l看了一下java的20798,刚好就是服务A。

究竟服务A在跑什么,毕竟是测试环境。于是使用top -Hp 20798看一下是哪个线程在跑,如下图:

发现线程20840占用cpu非常高,其他几乎都是0。通过以下命令输出该线程id(20840)的16进制:

printf "%x" 20840

输出如下:

线程id(20840)的16进制是5186。

然后使用以下命令打印出该线程的堆栈信息:

jstack -l 20798 | grep -A 20 5168

输入如下:

发现占用cpu的进程是jvm的GC线程,于是猜测是不是由于一直在进行FGC导致cpu飙高,于是使用以下命令看下FGC的频率和耗时:

jstat -gc 20798 1000

输出如下:

发现,果然是不断地在进行着FGC,并且每次FGC的时间一直在升高。是什么导致一直都在FGC呢?是有大对象一直在创建,回收不了?于是使用以下命令看下heap中的对象情况:

jmap -histo:live 20798 | head -20

输出如下:

发现一个业务类对象竟然有150w+个,并且占用了264M的堆大小,什么情况,并且这150w+个对象还是存活的(注意jmap使用的时候,已经带上了:live选项,只输出存活的对象),吓我一跳。于是赶紧使用以下命令打出线程堆栈来看一下:

jstack -l 20798 > jstack_tmp.txt

输出如下:

然后使用如下命令在输出的线程堆栈中根据对象类查找一下:

grep -C 30 'omments' jstack_tmp.txt

输出如下:

猜测是由于一下次从db load出了太多的CommentsEntity。

于是使用以下命令dump出heapdump出来重复确认一下:

jmap -dump:live,format=b,file=news_busy_live.hprof 20798

把heapdump文件news_busy_live.hprof下载到windows本地,使用mat工具进行分析,第一次打开发现打不开,毕竟news_busy_live.hprof有3G那么大,mat直接报OOM打不开,发现mat的配置文件MemoryAnalyzer.ini里面的配置-Xmx1024m,heap size才1G,太小了,于是改成-Xmx4096m,保存,重新打开mat,再打开news_busy_live.hprof文件即可,如下图:

发现mat已经帮我们分析出了内存泄漏的可疑对象,233w+个对象(前面通过jmap命令输出的150W+个,是后面为了写文章而专门重现的操作,这里的233w+个是当时真的出问题的时候dump出来的heap dump文件),太恐怖了。

通过以下操作,查看

点击exclude all ....,因为弱引用,软引用,虚引用等都可以被GC回收的,所以exclude,输出如下:

发现一共有6个线程引用了那233w+个对象,于是去前面dump出来的线程堆栈跟踪以下这几个线程的情况,发现堆栈里面刚好这几个线程也是在处理comments相关的逻辑,这个是刚好碰巧,一般线程id都对不上的,毕竟线程处理完之后就释放了的。所以我们还是看回前面线程堆栈的信息,这里贴出根据关键字"omment"搜索出来的线程堆栈的信息,如下:

"XNIO-5 task-77" #248 prio=5 os_prio=0 tid=0x00007fc4511be800 nid=0x8f7 runnable [0x00007fc3e5af2000]   java.lang.Thread.State: RUNNABLE       ...        at cn.xxxxxx.news.commons.redis.RedisUtil.setZSet(RedisUtil.java:1080)        at cn.xxxxxx.news.service.impl.CommentsServiceV2Impl.setCommentIntoRedis(CommentsServiceV2Impl.java:1605)        at cn.xxxxxx.news.service.impl.CommentsServiceV2Impl.loadCommentsFromDB(CommentsServiceV2Impl.java:386)        ...        at cn.xxxxxx.xxxs.controller.vxxx.xxxxController.getxxxxxx(NewsContentController.java:404)        at cn.xxxxxx.xxx.controller.vxxx.xxxxxController$$FastClassBySpringCGLIB$$e7968481.invoke()        ...        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)        at java.lang.Thread.run(Thread.java:745)​   Locked ownable synchronizers:        - <0x00000000f671ecd0> (a java.util.concurrent.ThreadPoolExecutor$Worker)​    

从上面的堆栈信息,结合前面的猜测(猜测是一次性从db load出太多的CommentsEntity),猜测应该是函数loadCommentsFromDB一次性从db load出太多CommentsEntity了。于是看了一下业务代码,发现load出来的commentsEntity会放到redis的某一个zset,于是使用redis destopmanger看一下这个zset的数据,发现这个zset有22w的数据,从中找出几条,发现对应的newsPk都是同一个,根据newsPk在db中找一下该newsPk的comments总记录,发现该newsPk的comments记录数是38w+条,那就是这个问题了,一次性从db中load了38w+的数据到内存。

一次性load那么多数据到内存,这肯定是一个慢查询,不管是db还是网络io,都肯定很慢。然后发现业务代码还会有一个for循环,把这个CommentsEntityList遍历一遍,一条一条放到redis,这也是一个非常慢的过程。

然后我去看了服务A的access log,发现在短时间内,请求了该newsPk多次数据,所以就导致了jvm的heap空间不够,然后出现不断FGC的现象,并且该newsPk的请求,由于超时,都在网关超时返回了。

为了验证这个问题,我把相关的redis缓存删除,然后调用该newsPk的接口获取数据,发现很慢,并且cpu立刻飚上去了,然后调多几次,并且不断地进行FGC,至此已经复现了该问题,和猜测的一样。等数据load到redis之后,再访问该接口,就很正常没问题。

上面发现问题的代码,找时间做一下优化才行,先重启服务A,让服务可用先。

oralce load的时候使用触发器会导致load慢吗_一次FGC导致CPU飙高的排查过程相关推荐

  1. 一次FGC导致CPU飙高的排查过程

    今天测试团队反馈说,服务A的响应很慢,我在想,测试环境也会慢?于是我自己用postman请求了一下接口,真的很慢,竟然要2s左右,正常就50ms左右的. 于是去测试服务器看了一下,发现服务器负载很高, ...

  2. json.tojsonstring 导致cpu飙高_阿里调试神器立功了!进程导致Kubernetes节点CPU飙高的排查与解决...

    来源:https://www.cnblogs.com/maxzhang1985/p/12673160.html 一.发现问题 在一次系统上线后,我们发现某几个节点在长时间运行后会出现CPU持续飙升的问 ...

  3. 记一次jvm疯狂gc导致CPU飙高的问题解决

    在环境上遇到tomcat频繁gc导致cpu load飙高的问题,本来想自己写一个文章的,看到这个偷懒转载一下. 线上web服务器不时的出现非常卡的情况,登录服务器top命令发现服务器CPU非常的高. ...

  4. jvm 崩溃日志设置_记一次JVM疯狂GC导致CPU飙高的问题解决

    背景 线上web服务器不时的出现非常卡的情况,登录服务器top命令发现服务器CPU非常的高,重启tomcat之后CPU恢复正常,半天或者一天之后又会出现同样的问题.解决问题首先要找到问题的爆发点,对于 ...

  5. 一次nacos 导致的 CPU 飙高问题

    序 今天下午突然 出现 测试环境 cpu飙高,干到了 60%,其他项目 响应时间明显变长...有点吓人,不想背锅 项目背景 出问题的项目是 需要连接各个不同nacos 和不同的 namespace 进 ...

  6. jenkins漏洞导致服务器中了挖矿病毒!cpu飙高351%!看我如何消灭它!

    作者:SilentBillows,资深Java工程师,架构师小秘圈特约作者!欢迎大家投稿,在后台回复投稿即可! 一, 定位问题 1.发现cpu异常,查看对应的进程信息 [root@versionlib ...

  7. nuxt.js之SSR服务端内存泄漏导致CPU过高的解决过程

    问题 最近在公司维护nuxt项目时,线上遇到了一个问题--访问网站,网站会报502或者JS.css资源报502. 去运维那一查pm2,项目node服务器的CPU达到了100%,实际上这段时间并没有人访 ...

  8. Mysql导致CPU飙高的问题

    出现CPU飙高时操作 出现cpu飙高时使用先试用top命令查看进程,确定是java进程还是mysql 找到进程号 <pid> 一.如果是mysql 1.那么使用mysql终端或者数据库链接 ...

  9. CPU load和CPU使用率飙高,系统性能问题如何排查?

    压测时或多或少都收到过CPU或者Load高的告警,如果是单机偶发性的,经常会认为是"宿主机抢占导致的",那事实是否真是如此呢?是什么引起了这些指标的飙高?网络.磁盘还是高并发?有什 ...

最新文章

  1. 电动车逆变器的基础知识
  2. 构造 ---- 最小没出现过的数(逆向构造) D. Replace by MEX
  3. 前沿速递:Maven中央仓库新增依赖漏洞提醒功能
  4. R语言:paste函数解析
  5. 编译原理实验语义分析_Windows MVSC编译器实现Xtended Flow Guard(XFG)保护机制的原理分析...
  6. java中的Cookie是什么_第74节:Java中的Cookie和Session
  7. 复工之后,如何让自己的时间更值钱
  8. docker 管理工具_详解Docker可视化管理工具shipyard--部署教程及功能展示
  9. android播放视频来源库,一个强悍而优美的Android视频播放器
  10. smartupload 路径不存在_使用SmartUpload上传文件不成功
  11. chrome清楚缓存并硬性重新加载
  12. 51单片机学习笔记——DA转换
  13. ssm+vue企业员工考勤请假网上办公OA自动化系统java
  14. item_search_coupon - 优惠券查询(淘宝) 该接口的使用主要是查询商品是否有优惠券,例如满一百减50元,相似商品有优惠券的都会显示出来;
  15. 国外LEAD联盟,S联盟被关联
  16. 人工智能专家:AI并不像你想象的那么先进
  17. bzoj 1646 bfs
  18. JQuery | JQuery语言 | JQuery基础 | JQuery语言基础
  19. Centos7扩容根目录
  20. LoRa技术的基本认识

热门文章

  1. web 小程序 ch2 第一个小程序
  2. Greenplum【集群搭建 01】局域网 CentOS 7.9.2009 环境 GreenPlum 6.13.0 集群规划+配置+安装+内核参数调整(应用实例分享)
  3. 【Linux病毒】腾讯云 cron、sshd 进程CPU占用超95%(亡命徒 Outlaw 僵尸网络攻击)问题排查及处理步骤
  4. 【Java开发问题】对象封装+固定排序+list All elements are null引起的异常处理+Missing artifact com.sun:tools:jar:1.8.0
  5. 10丨 Redis主从同步与故障切换,有哪些坑
  6. java redis释放连接_redis在应用中使用连接不释放问题解决
  7. SpringMVC-拦截器快速入门
  8. 「中间件系列一」kafka消息中间件
  9. Idea使用技巧总结(未完待续)
  10. Java判断上传的文件是否是图片,如果是就对上传的图片进行压缩