需求场景:
需要对文件进行上传,文件太大的情况下,将整个文件作为一个单位进行上传会出现以下几个问题:
- 增加传输时间和占用带宽
- 如果网络发生中断或者其他错误,可能需要再次重新上传整个大文件
解决方案:
将大文件切分成数个小文件再进行上传。会有以下优势:
- 将大文件切分成小文件,可以并行上传这些小文件,提高传输效率
- 将大文件切分成小文件可以降低单个文件上传失败的影响范围,只需要上传受影响的小文件
- 可以实现断点续传,在传输过程中中断,也能从断点处继续上传,而不是上传整个大文件
遇到的问题:
将大文件切分成小文件进行上传,通过http协议可以上传成功,但是切换到https协议后出现了请求超时的问题
问题分析:
http:每次请求都需要建立一个新的连接,每次只能处理一个请求,该请求响应返回之后才会处理下一个请求,超过数量将会排队等待
https: 加密传输,通过SSL/TLS 协议对数据进行加密,保证数据的安全性。支持多路复用,可以在一个连接上同时发送多个请求,并且可以同时处理多个请求。同时发送请求的数量太大,无法处理这么多的请求数,导致排队出现等待,发生连接超时问题,这个不太成立,因为并发的数量当时就十几个小文件,并发数量较少,仍出现连接超时,可能由服务器逻辑问题引起。
问题解决方案:
- 优化服务器配置,确保服务器的处理能力和配置足够满足上传的需求,避免因为服务器性能不足导致超时。但是服务端说他没啥问题╮(╯-╰)╭
- 使用
fastq
js库,npm地址:https://www.npmjs.com/package/fastq 。利用fastq的队列机制,避免服务器过载导致超时问题。
import fastq from "fastq"; const upload = ({ item, i }) => { const data = { data: item, index: i, total: chunkNum, filaName: file.name } const params = { type: "upload", data: data }; return uplodRequest(params); } const q = fastq.promise(upload, 3); const requestList = chunkBase64List.map(async (item, i) => { return await q.push({ item, i }); }) const promiseAllRes = await Promise.all(requestList);