导入导出异步任务总结
heyong-2015 opened this issue · 5 comments
背景
导入导出发展史:最开始的时候导入导出都是由后台实现,前端就比较轻松啦。但是没爽多久,前端也开始考虑是否可以接手做导入导出,随之出现了gm_xlsx(下面会有简单说明,代码在github,想深入了解的人请阅之)。在过了好些天,由于gm_xlsx中使用的xlsx库比较大,而且也不是每个地方都需要用,为了性能,我们再次引入了按需异步加载gm_xlsx这货,于是乎出现了gm_service(下面会有简单说明,代码在github,想深入了解的人请阅之)这个工程。说了这么多,性能的问题还是存在,所以后台最后又搞了一个异步任务(下面也会有简单说明,先了解一个概念,如果深入了解,代码在station上,请阅之)来解决批量操作引发的性能问题,于是乎一系列的东西出来。
工程解释
gm_xlsx:这个库主要是用来导入导出的。本库提供了jsonToSheet, tableToSheet, sheetToJson这些方法。
-
jsonToSheet这个方法,是json数据生成导出文件(比如,后台给我们返回的list,我们通过返回的list生成到处文件),用于导出文件功能。
-
tableToSheet这个方法,是通过表格生成导出文件(比如,有一个table,我们可以传入table元素生成导出文件),用于导出文件功能。
-
sheetToJson这个方法,是导入一个文件,然后解析导入文件,生成json数据。
gm_service:这个库主要是用来提供一些与业务相关的东西。比如说:异步按需加载,其中导入导出按需加载的方法就被抽到require_gm_xlsx.js文件中,要想深入了解的可以深入解读代码。(特别说明一下,service里面还有其他按需加载,比如echarts,pdfmake啥的,是一个公共的提供与业务相关的库,多去看看,肯定能有不少收获的,建议大家有时间都去看看)。
- requireGmXlsx这个方法,是用来异步按需加载xlsx的方法,具体怎么使用,在station中有实例,大家可以全局搜索这货,知识点挺多的。(这里顺便解释一下,为啥要搞按需加载:因为xlsx这个库比较大,如果是全局加载的话,很多页面都用不着这个库,但是加载了就会影响性能,所以搞了一个按需加载)。
异步任务
-
诞生原因:在我们系统中有很多大量的批量数据处理,比如说导出,需要导出的数据两很大,后台需要比较长的时间来处理。在以前没有异步任务之前,只能一直等,如果时间超过设定请求超时时间,就会报错,而且在这段时间内都只能等待。但是介入了异步任务以后,碰到这种大量的批量操作,需要比较长的耗时,这时候,后台就会把这个任务挂起来。就不需要等待了,这个任务的完成与否我们可以通过一个任务列表获取到。这就很好的解决了系统中存在的请求超时异常问题,请求长时间等待问题,总之还有不错的。。。。
-
使用场景:数据导入,导出,搜索等批量操作都有可能会使用。。。
异步任务导入导出使用说用
-
导入导出分类:异步导入导出(后台需挂起异步任务)和同步导入导出(不许挂起异步任务 )
-
同步导入导出:首先说一下简单的同步方案,以前所有的导入导出都是后台做,后面探索一下,发现前端做导入导出也比较方便,所以就出现了前面说的gm_xlsx库,用来实现导入导出功能。(顺便说一下,以后只要是新加的同步导入导出都前台做)
-
异步导入导出:当后台收到批量请求时,发现需要处理耗时比较长的时候,这时候就会在后台挂起异步任务,同时返回一个结果告知前台,这个异步任务已经挂起了,前段可以先处理自己的事情了。但后台处理完了这个异步任务的时候,如果是导出就会生成一个导出文件,然后把这个文件上传到服务器上。前端可以通过获取异步任务列表获取到这个异步任务的相关信息(已完成,未完成所有的异步任务信息都是通过这个异步任务列表获取),如果导出完成,信息中就包含这个导出文件的下载地址,然后用户就可以通过这个下载地址下载需要导出的文件。(这里面还有不少知识点,这里就不展开了,代码在station上,大家如果想了解更多,可以详细的阅读代码)。
-
如果判断同步还是异步:后台会在返回的消息中返回不同的code值,前端可以通过这个code值来判断是同步还是异步。如果是同步,后台同时也会返回需要导出的数据列表,这个时候前台还需把数据列表通过gm-xlsx导出文件。如果异步,那前端只需按照产品需求处理(例如唤起一步任务列表,提示批量任务已开始执行请到异步任务列表查看之类的。。。。)剩下操作就行。
异步任务流程图
特别强调
这里面涉及的东西还挺多,如果大家只是看看,我感觉理解起来有可能没那么容易,也可能会漏掉一些东西,所以我还是建议大家去读读代码,读完代码再来看一遍也许会有更多的收获。这里的代码,还是挺建议大家去认真阅读的。最最最最最重要的事情,也是最最最最最想强调的事情就是里面有可能会有不对的地方,大家喷轻点,年纪大了,大家多关心关心老人家!!!!
说明
上面说的有不对的地方敬请谅解,最终解释权归作者所有。
gm_xlsx:这个有疑问可以找敏仪或何勇了解。
gm_service:这个有疑问可以找敏仪了解。(敏仪提供的)
station异步任务:这个有疑问可以找桂松了解。(里面2秒钟刷新一次都知道,看过代码,比较认真)。
以上所有有疑问的都可以找雅堂了解。
有几个疑问,想了解下
1 为什么最开始是由后台做?
2 前端做xlsx有什么顾虑,兼容性如何,性能如何
3 “说了这么多,性能的问题还是存在”,这个性能问题是指?是批量操作引发的?还是数据流大引起的?
3 前端生成xlsx供下载这part,有什么策略么
4 生成 xlsx 上有遇到什么难点么?特殊字符上?
经过勇哥的精彩讲解,即使没接触过导入/导出,也对整个过程有了一个清晰的认识。所以来谈谈个人对雅堂提出的几个疑问的理解
为什么最开始是由后台做?
- 一开始就没想过由前端做
- 通过HTML5的
File
相关API,前端可以操纵二进制,从而能够实现xlsx<->json
的互相转化,但是考虑到浏览器端的限制(兼容性、面对大数据/复杂Excel的处理难度)没做
前端做xlsx有什么顾虑,兼容性如何,性能如何
复杂excel的处理难度/需要用到新API->兼容性问题。性能:通过浏览器给定的接口去操纵二进制,可以视作执行普通的js代码,但是可能出现计算密集,导致浏览器卡顿/卡死
“说了这么多,性能的问题还是存在”,这个性能问题是指?是批量操作引发的?还是数据流大引起的?
因为是同步所所以需要后端立刻处理数据,返回结果,批量操作/大数据量/多个请求 这些场景会产生大量的计算,占用服务器资源,导致后面收到的请求来不及响应。
前端生成xlsx供下载这part,有什么策略么
没接触过 不懂。。
生成 xlsx 上有遇到什么难点么?特殊字符上?
需要符合xlsx格式规定,比如sheet名字不能是特殊字符等等。在处理复杂excel比如包含图表、公式可能有难度。
再简单总结一下gm导入导出发展过程(权威解释请看楼主):
- 因为 烫烫烫,所以一开始xlsx就是后端做。
- 后来为了减轻后端压力,同时也不给浏览器端带来过大计算压力,将简单的数据导入导出交给前端,分摊了一部分计算量。
- 即使如此,后端在面对复杂excel时,仍然可能出现计算量过大,后端请求被阻塞,来不及返回响应,导致浏览器等待时间长,用户体验不好。
- 改成异步后,用户通过任务窗口知道任务的执行进度,同时在后端因为是异步的,不需要立刻返回文件内容,可以方便后端实现一些优化,比如通过一个专门的TaskService去调度/管理/分发这些任务,而不会影响到正常的请求->响应流程,保证了后端服务的高可用、稳定。这就很厉害了。
1. 为什么最开始是由后台做?
这个历史比较久,我来这的时候,已经是后台做了。我的怀疑:一方面是开始前端没引入库,所以想自己实现比较困难。另一方面可能现在很多导入导出都后台做,所以直接后台做了。但是后来有为啥要转前台做,是因为后台要导出数据需要解析数据,然后解析数据又比较麻烦。后台应该只管数据,不管格式,所以后台抛出了前端能不能实现,然后前端就开始研究导入导出,所以gm-xlsx诞生了。
2. 前端做xlsx有什么顾虑,兼容性如何,性能如何
3. “说了这么多,性能的问题还是存在”,这个性能问题是指?是批量操作引发的?还是数据流大引起的?
性能问题主要都产生于批量操作,批量操作的时候,比如说批量导入的时候,后台拿到导入数据后,很多会需要对数据就行校验计算处理啥的,如果数据量太大了,耗时就会比较长,对后台处理就会有性能影响。数据导出时,如果导出的数据比较多,后台也会耗时比较长,如果这个是耗时超过了消息请求设置的时间范围就会报错,导致导出失败。所以由于性能问题导致了许多bug。为了解决这些问题,异步任务便孕育而生了。
4. 前端生成xlsx供下载这part,有什么策略么
既然有导出,便会有下载。同步导出的下载是有gm-xlsx解决了,我们不需要处理。但是在异步任务中的下载便是后台给我们提供下载链接,前端负责下载。开始的时候我们用的是html5的一个功能,在a链接中加download属性,只要是有这个属性就能知道这是一个下载链接,但是由于这个属性的兼容性不是特别好,具体兼容那些浏览器可以查一下哈,所以后来就换了iframe这个东东,具体去station代码查看downLoadStaticFile方法
5. 生成 xlsx 上有遇到什么难点么?特殊字符上?
说到这里,便产生了一个bug,由于开始的时候考虑的不是很全面,对xlsx生成的文件的名称以及sheet的名称没有考虑,而这些名称又是可以通过用户自己填写,当输入的名称不符合要求是便会生成文件失败,而导致bug。所以我们在库里增加了正则表达式来处理和谐掉那些不符合规则的字符,比如“?”全用"_"替换了。
1 为什么最开始是由后台做?
导出是导出全部,前端每次只能获取到limit条数据。而且数据量太大的话,前端也hold不住。
2 前端做xlsx有什么顾虑,兼容性如何,性能如何
数据量大、复杂的表格展示、特殊字符、字体样式
兼容性(基于SheetJS/js-xlsx):
性能:试了一下,在mac和测试的电脑上,导出2w条数据速度在5s左右。但总感觉不太靠谱。
3 “说了这么多,性能的问题还是存在”,这个性能问题是指?是批量操作引发的?还是数据流大引起的?
如果数据量特别大(我们的客户确实也有这样的需求,统计好几个月的信息),并且如果后台没有落表,or需要实时去拉很多数据,or拉到的数据需要各种组合计算,那么就会让客户等很久很久,占用太多的服务器资源了。
4 前端生成xlsx供下载这part,有什么策略么
不造
5 生成 xlsx 上有遇到什么难点么?特殊字符上?
不造