2

前言

这周尝试做一个使用队列优化导出execl表的issue,因为服务器内存原因,多个导出任务同时进行可能会导致内存溢出,使用队列进行依次导出,减少服务器压力。
image.png
任务中还指出在队列等待时可以中途取消导出操作,此时应该是队列中删除相应实体.

队列

队列是一种先进先出的数据结构,区别于栈的先进后出,在java中队列只作为接口出现,一般使用链表实现其接口.
为了防止在导出过程中服务器宕机,也为了让用户可以下载历史导出记录,加入historyExportExcel实体,保存每次查询的查询参数即文件名等属性。
原先的导出逻辑
image.png
image.png

由于修改后需要分两种情况,一种情况是请求导出excel表时没有正在导出excel表的任务,那么直接导出。一种情况是请求导出excel表时有正在导出的任务,那么需要提示用户当前导出任务众多,已加入导出任务队列,请稍后在历史导出列表中查看
那么需要考虑的是第二种情况,后台如何告诉前台加入导出队列,比如说后台告诉前台一个当前导出队列的长度,如1,2,3。那么如何与直接导出时的导出进度1-100相区别

第一次修改

变成两次请求,第一次请求先请求当前导出队列长度,如果当前导出队列为0,则直接导出,如果当前导出队列不为0,则不发出请求,直接提示用户
image.png

第二次修改

老师告诉我可以根据响应头的content-type字段进行判断不同类型的值,如果通过输出流写入token,那么不会有content-type,也可以定义响应头为content-type,如果是return的值,那么content-type字段默认为application/json.
然后又根据content-type将刚才的两次请求再简化回一次请求,如果当前导出队列为空,则直接导出,通过输出流返回filename,如果当前到处队列不为空,则规定content-type为application/json。
遇到一个问题,即使返回content-type类型字段,也会有一个进度。当返回filename时,前台会获取进度1-100,前台根据进度值调用正在加载弹出窗。返回队列长度时,也会有进度,进度为1。此时也会调用正在加载弹出窗。
image.png
通过老师的指点,在前台打断点看一下返回数据类型
第一次

data = {type: 3, loaded: 1, total: 1}

第二次

data = HttpResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:8015/api/resident/exportExcel?page=0&size=10&loading-ignore=true", ok: true, …}

如果是filename的话,total值为100,如果为队列长度的话,total为小于100的值.
image.png
再加入实体状态字段,防止并发问题


小强Zzz
1.2k 声望32 粉丝