背景
最近有个学弟找到我,跟我描述了以下场景:
他们公司内部管理系统上有很多报表,报表数据都有分页显示,浏览的时候速度还可以。但是每个报表在导出时间窗口稍微大一点的数据时,就异常缓慢,有时候多人一起导出时还会出现堆溢出。
他知道是因为数据全部加载到jvm内存导致的堆溢出。所以只能对时间窗口做了限制。以避免因导出过数据过大而引起的堆溢出。最终拍脑袋定下个限制为:导出的数据时间窗口不能超过1个月。
虽然问题解决了,但是运营小姐姐不开心了,跑过来和学弟说,我要导出一年的数据,难道要我导出12次再手工合并起来吗。学弟心想,这也是。系统是为人服务的,不能为了解决问题而改变其本质。
所以他想问我的问题是:
有没有什么办法可以从根本上解决这个问题。
所谓从根本上解决这个问题,他提出要达成2个条件
比较快的导出速度
多人能并行下载数据集较大的数据
我听完他的问题后,我想,他的这个问题估计很多其他童鞋在做web页导出数据的时候也肯定碰到过。很多人为了保持系统的稳定性,一般在导出数据时都对导出条数或者时间窗口作了限制。但需求方肯定更希望一次性导出任意条件的数据集。
鱼和熊掌能否兼得?
答案是可以的。
我坚定的和学弟说,大概7年前我做过一个下载中心的方案,20w数据的导出大概4秒吧。。。支持多人同时在线导出。。。
学弟听完表情有些兴奋,但是眉头又一皱,说,能有这么快,20w数据4秒?
为了给他做例子,我翻出了7年前的代码。。。花了一个晚上把核心代码抽出来,剥离干净,做成了一个下载中心的例子
超快下载方案演示
先不谈技术,先看效果,(
完整案例代码文末提供
数据库为mysql(理论上此套方案支持任何结构化数据库),准备一张测试表t_person。表结构如下:
CREATETABLE`t_person`(`id`bigint(20)NOTNULLauto_increment,`name`varchar(20)defaultNULL,`age`int(11)defaultNULL,`address`varchar(50)defaultNULL,`mobile`varchar(20)defaultNULL,`email`varchar(50)defaultNULL,`company`varchar(50)defaultNULL,`title`varchar(50)defaultNULL,`create_time`datetimedefaultNULL,PRIMARYKEY(`id`));
一共9个字段。我们先创建测试数据。
案例代码提供了一个简单的页面,点以下按钮一次性可以创建5w条测试数据:
这里我连续点了4下,很快就生成了20w条数据,这里为了展示下数据的大致样子,我直接跳转到了最后一页
然后点开下载大容量文件,点击执行执行按钮,开始下载t_person这张表里的全部数据
点击执行按钮之后,点下方刷新按钮,可以看到一条异步下载记录,状态是P,表示p
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.