您现在的位置是:首页 >  云笔记 >  开发随笔 >  文章详情

excel导出大数据量时服务器cpu过高tomcat卡死问题排查

admin   2019-01-14 14:50:24   265人已围观

       最近发现一套线上生产系统每周一都会出现宕机的现象,CPU很高,持续几分钟后tomcat直接卡死,系统无法登陆刷新无反应,重启后又回复正常,各种定位各种检查。最开始想到的是不是有啥挖矿程序每周一自动启动挖矿,所以先后扫描了服务器检查了定时任务都没有发现问题。后来在检查tomcat的访问日志(localhost_access_log.yyyy-MM-dd.txt)发现每周一都有人在我的服务器上大量导出excel,导出的时间点和服务器CPU爆满,磁盘读写这些时间点刚好吻合:

cpu使用率爆满

tomcat的localhost_access_log日志

     看到这里我就猜想可能是excel导出模块程序没有处理好,在导出大量数据的时候内存溢出,tomcat卡死;检查了一下导出前的查询日志,发现导出前用户查询到的数据是12000条左右,立马在本地模拟测试一下发现tomcat在第二次执行导出的时候就直接卡死,eclipse也直接提示error :Unhandled event loop exception Java heap space,基本上就证实了我的猜想。剩下的问题就是怎么解决这个问题。

    我的服务器环境是CentOS7.6, 64位 4核,8G内存,tomcat7, poi3.6.jar. 大概在12000条数据的excel导出就卡死。设置jvm参数已经是设置到最大了,没办法再往上加内存分配了。第一阶段我做了如下几个优化处理:

  1. 1、将页面的导出按钮在点击导出后立即置灰,待下载完成后等待几秒后恢复可点击;防止用户再等待过程中多次点击。
  2. 2、使用js禁止用户刷新导出操作页面(效果不是很明显)
  3. 3、网上传说poi最新版本4.0已经优化了这种问题,可以升级尝试一下:http://poi.apache.org/  (前提是最低支持JAVA8)
  4. 4、代码优化:将导出过程中数据日志减少,减少对象的新建(new 新对象),必要的对象放在循环外new。变量声明到底在循环外部能有效的降低耗时        和内存消耗;还有一个就是一定要关闭流输出fout.flush();fout.close();
  5. 5、跟需求方商量将excel导出上限设定在10000条记录左右。

第一阶段我就做了这些优化处理,目前效果还在观察中,如有新问题或者进展后续更新。


onekbit云笔记整理分享


分享到:

编辑发布时间:2019-01-14 14:50:24