记一次生产环境CPU100%排查和性能优化

前几天中午快吃饭的时候,运营突然和我们说后台管理系统瘫痪了(/(ㄒoㄒ)/~~这还让不让人吃饭了)。不过还好只是后管,不然压力陡增啊。赶紧上服务器瞅一下是怎么回事,发现CPU满载了,这是什么情况,后台一般没什么大计算量的工作,怎么会突然满载了呢。

运行环境

操作系统:Centos 6.8
应用服务:Tomcat8
语言:Java

问题排查

赶紧把CPU满载排查流程走一遍
1.使用jstack > t.log 导出当前的线程堆栈
2.先使用top命令查找当前消耗CPU最高的进程pid
3.top -pH 找到当前进程下正在消耗CPU的线程Id.
4.将线程ID转换成16进制ID,并在线程堆栈里面找到对应的线程
发现都是gc线程,gc异常了?赶紧用jstat -gcutil 1000 5 看了下当前垃圾回收情况,发现年轻代和老年代都满了,一直在进行Full GC,导致CPU满载,既然是垃圾回收的问题,先重启服务器,将服务恢复再说,发现重启后服务恢复了正常。

猜想

到底是什么原因导致垃圾回收异常呢,内存泄漏了吗?应该不会,最近没有进行后管的迭代,那不是内存泄漏,立马猜想可能是大对象导致的,后台有可能出现大对象的情况只有订单导出了。赶紧问了下运营,是不是谁在导出订单,问了果然是的。但是问题来了,之前订单导出都没有问题,为什么这次导出订单会导致老年代占满而且Full GC回收不了呢。想到后台订单导出比较耗时,且导出按钮没有等待服务器响应之后才恢复的机制,猜想是不是运营等待过程中点了多次导出导致的呢。

验证

想到这里,赶紧在测试服务器上进行验证,发现完全符合猜想。

解决问题

既然是因为多次导出导致的问题,那我们只要将后台的导出任务改成串行不就可以了吗,而且业务上也不受影响,于是加上了分布式锁,问题解决。

进一步优化

1.导出代码性能优化

平常运营老抱怨导出订单性能差,单量大就要等很长时间,而且不知道要多久才能导出来,前端也有等待超时时间。索性这一次整体优化一遍,看了下代码,订单从订单表查出来之后循环遍历对每条记录做做大量的信息补充,平均每条耗时20-50ms左右。我擦,这怎么可能快,10000条不是就3,4分钟过去了吗。因此将信息补充过程改成了并行处理。在测试服务器上测了一下瞬间快了将近10倍,瞬间感觉身心愉悦

2.流程优化

考虑到导出订单量大的话,耗时特别长,因此进一步进行了流程优化,将导出订单改成了异步。流程如下:
1.运营先提交一个导出任务,然后就可以去做其他事情了
2.后台开启一个线程执行导出任务并立即返回响应;
3.导出完成之后将Excel上传到文件系统,更新完成状态,记录Excel地址到记录。
4.下载文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值