大报表高并发导出 Excel 的限流措施

大报表导出因数据量巨大,导出 EXCEL 文件时间长。高并发导出请求会同时启动过多的线程执行导出服务,由于单次执行时间长,服务完不成堆积起来,对 cpu 的竞争非常激烈,可能原本要一分钟执行完毕的任务,拖长到几十分钟,最后经过漫长等待所有用户几乎同时完成。所有用户都处于等待中,却缺少有效反馈,可能以为导出出问题了,而失去耐心。这时不如从服务器端控制,限流或排队。

而且目前没有对大报表并发导出 EXCEL 内存需求的明确指导。

因此做了以下测试,从中找规律以解决上述问题。(本文不讨论大报表导出时与数据库交互的开销)

测试过程简录放在文后,直接说结果:

一,关于大报表导出内存消耗

计算和测试结果依据 jvm 堆快照和 cpu 占用率分析:可容纳得总并发数与单页大小(格子为单位),和 jvm 最大内存大小有关。

大报表单元格实例大小较为稳定,约 107B(不包含图片时)。

报表页实例存在很大的矩阵对象,大小随格子数增加而近似线性增加,约合

(一页单元格内存大小)*0.25;

即总大小占用约为

(一页单元格数量 *107B)*1.25

= 一页单元格数量 *133.75B

= 一页单元格数量 /100000 * 12.76M  (换算成兆)

单页 100000 单元格量,单次导出 jvm 至少需要 12.76M 空闲。

注意虚拟机自身和其他应用、线程对虚拟机内存同样有消耗,在较为空闲的 jre1.8 环境启动虚拟机做上述 [单次][100000/ 页] 导出至少还需要额外的 200M(不考虑减少 GC 次数得需求)。

并发累计次数 *12.76M* 一页单元格数 /100000 = JVM 空闲空间

举例:

若控制每页显示 10000 数据量(例如 500 行 *20 列),虚拟机大小为 500M,不考虑其他应用,则支持最大并发数:

(100000/10000)*(500-200)/12.76 = 约 234 次并发

二,关于 cpu 工况与并发数量的关系

cpu 占用率随着导出线程增加而增加,当并发数量到达一定高度时候,若 JVM 内存紧张,GC 比例会开始增加,增加时间开销,也应据此调整 JVM 大小。

过少的并发是性能浪费。环境单机,本地,锐龙 R7,8 核 16 线程 cpu,经过测试,上述单页 10000 格数据,总数据量 120W 的大报表,cpu 占用会在 10-15 并发达到峰值;并发数量大于 10 时平均每个文件需要的导出时间最低。

当并发数量大于 10(平均每个文件需要的导出时间来到最低)时,导出总时长虽然随着并发数量增加而增加,但平均每个文件导出时长没有很大变化。

综上,应用并发编程的思想,若要提高系统性能,应结合自身工况:

1,合理设置 JVM 空间

2,分布式部署报表缓解单机压力

3,结合工况对大报表导出服务限流

4,总导出时间相近,单个文件导出时间相近情况下,一部分客户若可以先获得结果,体验会更好一些(增加排队机制)

三,解决方案

对于 1,2 客户可以自行调整。对于 3,4 现在已增加如下措施:

报表应用增加针对大报表导出的限流、排队机制配置。这是两种不同的方式。

1,如果要使用直接的大报表导出限流,可以在报表应用配置文件中增加 bigReportExcelExportLimit 属性:

<Server>
<property name="bigReportExcelExportLimit" value="10"/>
……
</Server>

此时,大报表导出功能被限流,在此应用上,任意用户导出任意大报表均会进入计数,当数量到达设置的 10 的时候,后续用户请求导出会直接被拒绝并返回,并且弹框提示:【大报表导出队列受限,请稍后再试】。直到某(几)个用户完成了导出,数量被释放,其他用户此时再请求才可以进入正常导出大报表的状态。

2,排队机制目前处于试用,如果要使用排队机制,可以在报表应用配置文件中增加以下属性:

<Server>
<property name="bigReportExcelExportDirectory" value="D:/testQueueDir"/>
<property name="bigReportExcelExportQueueCapacity" value="100"/>
<property name="bigReportExcelExportExecutorThreads" value="10"/>
<!--  0下载后不保留文件,1保留文件30分钟 -->
<property name="bigReportExcelExportFileManagement" value="0"/>
<property name="bigReportExcelExportTempCleanInterval" value="30000"/>
……
</Server>

1) 这里需对此机制进行解释,以理解上述配置概念:

排队导出 EXCEL 的队列基于并发安全的阻塞队列开发。队列有一定容量,到达容量最大值后,后续大报表导出 EXCEL 请求被拒绝,同上面限流机制。队列中的请求被设置好的 n 个处理器处理,既并发处理数量。由于客户不会快速即时地获得导出结果,而是获得排队、导出状态,文件实际被导出到硬盘,供客户下载,下载后即删。

因此我们需要配置:

bigReportExcelExportDirectory---- 大报表 Excel 临时文件导出到硬盘的位置,绝对路径

bigReportExcelExportDirectory---- 队列容量,可大可小

bigReportExcelExportExecutorThreads---- 并发数量,比如我们测试结果 10 次并发合理

bigReportExcelExportFileManagement---- 导出后文件管理策略

bigReportExcelExportTempCleanInterval---- 策略 1 时间间隔

2) 其中,【导出后文件管理策略】一向目前有两个值可选 0 代表硬盘临时文件被下载后立即删除;1 代表硬盘临时文件从生成完成开始 30 分钟超时,才会被删除。而策略 1 下的文件超时检查时间间隔由【策略 1 时间间隔】决定。注意:策略 1 可方便单个页面反复下载,但同时会更多地占用硬盘空间(一定时间才会清理一次),而且临时 Excel 文件也都很大,要谨慎使用。

3) 上述配置需要再报表应用启动前配置好,排队机制的可用以 bigReportExcelExportDirectory 的正确配置为标志。

4)以上配置正确,仅标志排队机制可用。至于使用它,我们需要通过前端 javascript 函数入口 function queueExcel(); 来请求导出 EXCEL。用户自定义某个事件(如:自定义图标点击)调用此函数即可。

5) 效果

imagepng

imagepng

imagepng

以下是测试过程的一些简录,使用 visualVM 监控:

5 并发耗时 129s

imagepng

imagepng

imagepng

10 并发耗时 189s

imagepng

imagepng

imagepng

15 并发  GC 0.0-1.0%,耗时 234s

imagepng

imagepng

imagepng

imagepng

imagepng

imagepng

20 并发耗时 312s

imagepng

imagepng

imagepng

imagepng

imagepng

30 并发耗时 465s

imagepng

imagepng

imagepng

imagepng

以下省略部分图片
50 并发耗时 794s

100 并发  GC 0.7-1.9% 耗时 1537s

200 并发

imagepng

运行 20 分钟后
imagepng

imagepng

imagepng

内存占用计算较为可靠。另由于时间严重延长,GC 占掉其中 3% 的时间,考虑网络链接超时变得不可靠、系统性能大幅下降,建议如下:

1,根据实际情况,分析堆空间,适当增加 JVM 内存,调优 JVM GC 策略

2,限制导出业务层并发数量,目前提供了 bigReportExcelExportLimit 报表应用参数,可硬性地限制并发数量,拒绝超限制导出请求

3,集群部署报表应用,以减轻单机负担

4,Tomcat 超时设置为 0

5,虚拟机设置 HeapFreeRatio、NewSize、NewRatio、SurvivorRatio、MaxPermSize 等改变 GC 空间比例,适当减少回收时机以提高 CPU 性能

6,线程增多可能导致大量任务不能完成处于等待,也可能导致内存短时间内占用增加

7,检查其他应用或报表其他线程内存占用情况

附:200 次并发测试 JVM 配置了 -XX:+HeapDumpOnOutOfMemoryError,过程中未发生 OOM 异常。

大量线程同时工作抢占 CPU,停顿时间长

imagepng

导出结果正常

imagepng

导出结束

imagepng

回收后空间富余

imagepng

以下是广告时间

对润乾产品感兴趣的小伙伴,一定要知道软件还能这样卖哟性价比还不过瘾? 欢迎加入好多乾计划。
这里可以低价购买软件产品,让已经亲民的价格更加便宜!
这里可以销售产品获取佣金,赚满钱包成为土豪不再是梦!
这里还可以推荐分享抢红包,每次都是好几块钱的巨款哟!
来吧,现在就加入,拿起手机扫码,开始乾包之旅



嗯,还不太了解好多乾?
猛戳这里
玩转好多乾