问题描述
我前端需要请求一个excel文件,但是这个excel文件是一个由后端动态生成的。详细解释就是:我前端传很多过滤条件,后端根据过滤条件,动态地生成数据,插入到excel表格。
这就导致一个问题,当数据量过大,3000条数据左右,http请求一直在连接中,导致报了499错误。客户端主动断开链接
原因分析:
网络请求一直在连接中,服务器或者ngix服务器判断时间过长,主动断开了链接。注:数据量过大,卡时间就卡在动态生成这一步。
动态生成指的是:后端先通过过滤条件获得需要的数据,然后不断地插入到excel表格中。
解决方案:
我的第一反应是,为啥我在其他网站下载文件时候就可以在下载栏慢慢下载,到了我这就会卡死。问了问朋友,tmd我忘了这些都是静态资源,服务器发了一次请求就完事了,不会一直处于waiting态。
很清楚,一般公司的对动态生成大文件的处理方式,让后端慢慢处理,然后通过一个类似邮件服务器再发送给用户。
同样的,在ABP中,我的解决方案就很明显了,发一个请求给后端,告诉要生成文件了,然后马上结束此http请求。后端生成的静态资源放在资源服务器上面(MINIO)。之后前端用RXJS接力这两个http请求,从MINIO获取静态资源
so,不想当产品的开发不是好测试 /(ㄒoㄒ)/
2022/9/19
今天优化的主要想法:
优化思路:将query和excel的生成下沉到domain层,然后前端发送http请求的时候,后端发一个eventbus,马上断开链接。之后交给后端去生成,存在MINIO中,前端每隔3s轮询MINIO中是否存在此excel文件,若存在就下载。
注意:需要新建一张表来记录存入MINIO的excel的Guid 获取后马上删除,保证MINIO 容量
但是这边有个问题,query是别人写在application层的,domain层无法引用application层的函数。这边可能需要自己去想法重新写query。另外。之前自己做的MINIO CRUD函数都是写在了application层。这一点我自己做的不好,这种通用的可复用的逻辑应该下沉。
2022/9/20
新的想法,或许我不应该放在domain层。domain层应该具体的业务领域层,是发生业务变化最为频繁的地方,是业务系统最核心的一层,是DDD关注的焦点和难点。这一层包含了如下一些domain object:entity、value object、domain event、domain service、factory、repository等。DDD实践的难点其实就在于如何识别这些object。我自己理解起来domain不应该去关注DTO,DTO被定义在applicationServiceContract里,不属于domain应该关心的范畴。
或许我应该在application层添加一个helper类?
2022/9/21
成功了,并没有把excel生成方法下沉。这次的解决方案是,前端请求一个printNotification接口,此接口仅仅是一个TASK<>无返回值类型的函数。内部异步调用excel生成函数。
😏接下来就要前端搞RXJS多个流的处理了,即学即用!前端碰到轮询的流处理,RXJS真是太好用了!
2022/9/21
TeamLeader提醒:
可以不用自己实现,用现成的框架,更加强大
ABP也为后台作业提供了一个抽象模块和几个后台作业实现. 它具有内置/默认的实现以及与Hangfire和RabbitMQ的集成.
突然想到一件事情,如果我使用websocket,是否还是无法保证生成excel的时间?如果按我自己的方式开启一个线程,传到minio的时间是很短的,3000条约10s左右。🤔