前提: 客户经理在整理月报时,需要上dashborad系统导出本月门店数据,因为本月数据已经超过上百万条,在导出时一直缓慢,等待很久都没下载好,过一段时间后,客户经理不耐烦后直接关闭网页,重新登录系统,发现系统都登录不上,也没有暴露错误喔。
解决流程:
通过上篇文章(如果不知道的,请看【cpu真的飙到270%】文章】),下面是我们的解决思路:
1.通过top定位我们系统的进程已经到达370%啦,4核的系统cpu基本占满,运维经理已经拉响警报。
2.通过pid定位tid,确定几个比较耗cpu的线程tid
3.stack 分析几个tid的线程(发现两个情况,1.存在等待某个锁的现象2.存在gc反复full的情况)
4.通过jstat -gcutil pid [time][num] 命令,发现 gc的新生代和老年代分别是100% 和90%,一直没有下降的趋势,断定可定是某些大对象存在老年代又一致没有释放。
5. 通过map -dump:live,format=b,file=[filepath] pid 获取dump文件,因为文件超过1G,所以先tar 压缩一下,可以缩小7倍,然后ftp 或者rz 拉取到本地
6.使用jdk 只带 的 jvisualvm.exe(bin 目录下),分析返现hashmap对象占用了40%。
能够最终到哪个实例对象,再结合stack 分析的定位代码后分析
7.发现在导出程序中,使用hashmap存储了一些基本数据缓存在内存中,轮询遍历获取es中的数据并结合存在haspmap的基本数据组装返回导出成csv数据(这里造成map中存在大对象又一致不释放的现象,导致cpu内存占满后出现等待锁等情况),所以我们已经明确出现的问题啦
解决方案:
1.将基础数据都缓存到redis中,每天同步一次数据库,用redis来当缓存这样就避免了
大对象存储在内存的问题,通过一周的修改和调试后,基本上导出功能已经不会导致到cpu狂飙啦。
因为这是现实中存在的实战,所以没有截图只是把解决思路给分享出来了啊,希望大家能够喜欢。
无敌TG