大数据量报表导出导致的生产页面卡死问题,OOM问题

前两天,客户反映我们的系统平台突然不能访问了,登录界面的验证码都加载不出来,然后运维人员也报告,我们有一台服务器的CPU使用率飙升至99%,且长时间下不来,这让我的脑瓜子咔咔疼。经过繁琐的手续在CPU自动降下来后,终于拿到生产日志,果不其然,内存溢出,可问题是,当时的情况是jps -l查看,进程还在,但是服务访问不了了,且因为cpu已经降下来了,使用jstack、jstat查看后,各线程也都正常,jvm内存统计也没有发现异常,GC次数非常高,但是因为系统运行很久了,以前导致的很高还是最近导致的很高,也不确定,至于哪个方法导致的,日志并没有记录清楚。
  但是隐约猜到是导出报表导致的,线上的报表导出功能最近使用的频率非常高,且数据量非常之大。
  于是,在测试环境,同数据量模拟了一下:

模拟生产环境,多次点击导出大数据量报表导致内存塞满,然后疯狂GC,CPU升高,页面无响应的问题。

    发现,在多个并发的大数据量导出的情况下,系统出现于生产环境一样的情况【本地开发没有那么多的数据量,因此一直没发现这个坑,以后要加大完善压力测试】,

打开jstat后,情况如下,一直在执行FGC
在这里插入图片描述
然后日志输出了OOM的问题,以及引起的其他的方法执行的错误的报错。
在这里插入图片描述
    经查询后发现,我们大的一次导出的数据量在二十几万的数据量,然后因为并发导出,且在导出生成对应的excel对象的过程中,对应的对象乘N倍生成,且这些对象在excel刷出到outputstream之前都会在内存中一直持有,导致内存一直在内存中引用,又释放不掉,导致内存撑爆。

   我们在导出的时候使用的是jxl工具,与POI一样都是一次刷出数据到输出流的。都不利于内存的释放,原本想分批次刷出数据的实验也失败了。jxl只会输出在第一次刷出之前的生成的excel的对象,且并不会释放之前的对象。

然后在查阅了文档之后发现,目前解决这个问题的方案,有以下几种:

  • 导出csv格式的数据
    缺点:数据格式不能保证
    优点:操作简单
  • 导出多个中间文件,将多个中间文件合并
    缺点:一个中间文件只能有一个工作表(sheet),合并文件也要耗时。
    优点:只要设定好每次请求数据大小,几乎不存在内存溢出问题。
  • 导出一个文件,循环分页请求数据,写入excel时分多个工作表(sheet)写入
    缺点:对于大量数据虽然利用循环分页的形式处理了一次性读取数据引发的内存溢出问题,但是,由于JXL在写入excel是,都是一次性写入的,所以还是回出现内存溢出问题。
    优点:能够实现10万条以内数据导出。
  • 导出一个Excel文件的xml形式,另存为.xls文件

    但是这些方式都不够友好且较为繁琐。

    然后看到了,阿里出品的一个EasyExcel工具,就可以将内存降低到很低的程度,因为它使用的是分批读写的形式来避免临时对象长期占用从而节省内存占用。

EasyExcel研究中。。。。。
未完待续。。。。

2020年1月12日20:24:55 更新
原报表导出三个并发导出后的virtualVM监控:
在这里插入图片描述
在这里插入图片描述
可以看到三个并发的报表导出的时候内存全部占满,并且cpu的使用率达到百分之百,后台查看,GC一直在执行,直到内存溢出。

然后我使用了EasyExcel进行了改进,改进后使用批量导出的方式,一次5000条数据,执行同样的一个导出报表的任务,数据量不变,看下内存占用的情况。
在这里插入图片描述
    可以看到内存占用 始终没有沾满,cpu的使用率也没有完全用满,升高后马上就降下来了,并且后台监控FGC次数只有两次,性能提升非常明显,

     但是!!! 时间提升比较长,几乎翻了一倍,好在可用性有保障,我们在前端对下载可以做一些其他的控制,让用户等待下,总比后台直接死掉要好很多。
在这里插入图片描述
在这里插入图片描述
    综上,EasyExcel对于导出报表在性能的提升上,非常明显,对内存的消耗非常之小,是一款非常不错的Excel报表工具!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值