关于前端:基于后端生成大文件导出所产生oom问题的思考

293次阅读

共计 1261 个字符,预计需要花费 4 分钟才能阅读完成。

背景

存在一个业务场景,通过前端点击事件,须要到 Mongo 数据库外面取数据并整顿成 excel 表格并发送给前端,数据量没有破十万的时候,所有还是比拟美好的。然而导出的量持续减少时前端页面间接卡死,后端也产生 oom 报错

问题定位

间接先说论断,就是后端在拿到数据生成 excel 表格时,将查问到的所有的数据定义一次性写入由 POI 定义在内存中的一个长期 excel 文件从而导致了 oom 报错。

解决办法

为解决问题先钻研 (bai du) 了一下 Poi 生成 Excel 文件的几种形式

HSSF:Excel97-2003 版本,扩大名为.xls。一个 sheet 最大行数 65536,最大列数 256。
XSSF:Excel2007 版本开始,扩大名为.xlsx。一个 sheet 最大行数 1048576,最大列数 16384。
SXSSF:是在 XSSF 根底上,POI3.8 版本开始提供的反对低内存占用的操作形式,扩大名为.xlsx。
采纳 Hssf 或者 Xssf 模式都会导致同样的问题产生,其根本原因是结构形式的不同

SXSSF 在结构时,会设置一个默认值 a,内存中最多只有 a 行数据,当超过这个数据时,就将内存之前的数据删除,并且会在硬盘中生成临时文件。不过也因为该个性,导致其生成数据的速度会比其余俩种形式慢,同时因为 Excel 版本兼容性是向下兼容。所以其实最优的形式是量大用 SXSSF,量小用 XSSF.

SXSSFWorkbook workbook= new SXSSFWorkbook(Int a);

新问题产生

刚刚有提到一点,SXSSF 模式的生成 Excel 文件比较慢。这又产生了一个新问题,批改了模式后,在理论前后端交互的时候,前端发送申请过去,常常在期待后端将文件生成再回应的过程中逐步失去急躁从而导致申请失败。

解决问题的几个思路

  1. 优化后端生成文件工夫。
    间接开始硬性医治,既然你后端处理速度慢就优化速度,例如优化 Mango 查问代码,应用多线程并发写 Excel 等等.
    该计划的长处是缩小了对外的整体查问的工夫。毛病是后端容易掉头发,而且多线程减少了开发和保护的难度;高并发压力转移到外部的服务器上,对其 QPS 响应提出了更高的要求。
  2. 将数据查问和下载的流程异步化。
    浏览器申请下载后,服务端立刻返回报表的惟一标识 Key 同时开始近程查问数据,客户端能够凭借该 Key 查问报表的生成进度,报表实现后就能够下载;或者应用另一种计划,服务器在报表生成实现后通过一些渠道(如 Long-Polling、WebSocket、即时通信软件、邮件等)告诉客户端下载。
    该计划的长处是并发能力强,不会阻塞服务器的 Web 连接池。毛病是须要开发 Key 的 CRUD 操作和相应的 UI;还须要在服务器端存储生成的报表文件。
  3. 服务端边生成文件,浏览器边下载报表。
    就像下载大文件一样,浏览器一直开和服务器的 Http 连贯,同时服务器一直向浏览器追加 Http 体数据直到报表生成完结。
    该计划的长处是开发难度低、速度快。毛病是数据查问是单线程的,速度较慢;而且文件下载会始终占用服务器的 Web 连接池,如果并发下载量较大可能会阻塞其余的 Http 申请。
正文完
 0