做项目的时候,经常会有导出数据的需求,当被导出的数据量较小时,直接实时导出即可。当数据量较大时,就不能实时导出了,会遇到如下问题:
1、内存溢出(Out Of Memory,简称OOM)
2、页面超时
3、单个sheet太大
这种情况,可以采用预约导出的模式,流程大致是这样:用户点击导出按钮,页面提示正在导出,数据库中生成一条任务,后端定时脚本取出任务,按照该任务的条件生成文件,提示前端用户文件已生成,用户下载该文件。
其中几个技术要点,我说下,首先是要建一个任务表,表结构如下
Task 任务表
id 自增id
task_name 任务名
task_params 参数
file_url 生成的文件路径
lasttime 完成的时间
createtime 创建时间
status 执行状态 (1初始状态,2正在执行中,3执行成功,4执行失败)
del 是否有效 (0有效,1被删除)
后端定时脚本每次取少量的任务,别取太多,不然单个脚本执行的时间太长了,比如这样取select * from task where status=1 and del=0 order by creattime asc limit 5,如果任务比较多,可以用多个定时脚本。
其次要注意生成excel的时候,要注意控制单个sheet的行数(不要超过1048576行),如果行数太大不利于用户打开查看,生成文件的时候,程序要注意拆分为多个sheet。
这个定时脚本要注意控制内存,变量及时销毁,防止脚本占用内存太大,导致执行失败。
后端生成文件成功后,要及时告知前端用户,比如用站内信、短信、websocket等消息机制,这个文件一般保留一段时间后,要有一个清理的程序来清理,否则您的服务器中会堆积大量垃圾文件,占用硬盘空间