这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
一、前言
针对弱网情况,断点上传有这些特点:
- 分块越小,意味着请求数也多。目前根据测试统计,
100KB分块大小的请求耗时是1MB分块大小的2倍左右。 - 在正常网络下发起请求,建议设置分块大小为
1MB及以上。 - 在网络信号弱等网络环境下上传对象容易导致上传失败,可以考虑将分块大小设置为
100KB,再重新上传。 - 分块大小设置越小,将来下载该文件时可能比较缓慢。
网络配置相关的排查思路,以下代码为具体的超时错误信息:
# iOS
2021/07/29 16:09:25:863 | Error NSUnderlyingError=0x283c78a50 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <3F6A8730-D689-4112-9057-41AB0CEEEAF9>.<4>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalUploadTask <3F6A8730-D689-4112-9057-41AB0CEEEAF9>.<4>"
), NSLocalizedDescription=请求超时。, NSErrorFailingURLStringKey=
综合以上分析过程,现推荐以下几种解决方案:
- 上传方式采用分片断点上传,每个分片的大小不超过
1MB。
采用分片断点上传,每个分片的大小不要超过
1MB,也不要小于100KB。 注:说明OSS服务器不接受小于100KB大小的分片。
- 添加重传机制,保证某一个分片上传失败后还可以继续上传。
- 增大超时时间。
(1)客户端如何判断弱网?
HTTP 在什么情况下超时?
HTTP 包括:请求 + 响应:
- 请求超时:客户端向服务器发起请求
- 响应超时:服务器接收请求数据后,处理过程过长(此期间与客户端没交互)
举个栗子:
- 客户端设置超时时间为 30s。
- 请求建立连接花费
16s,服务器响应花费15s,总共31s,这时候,客户端认为超时了。 - 所以,客户端超时时间需设置长一些。
- 但文件上传和下载,客户端与服务器一直在交互,所以会存在上传或下载一两个小时,且还没超时。
因为因素校对,客户端动态判断弱网,对于客户端难度较大。
(2)客户端如何处理?
在弱网环境下,可能存在这些情况:
- 客户端请求丢失了
- 客户端请求到服务端了并处理,但返回丢失了
- 客户端传输数据时,延时数据丢失并超时
分块步骤:
- 初始化分块信息:
uploadId - 上传分块:上传数据
- 结束分块上传:合并数据
上传分为:
- 普通上传
- 分块上传
综上因素,上传方式总结为:
-
普通上传:客户端设置超时为 30s,重试3次
- 文件大小小于
2MB使用这块
- 文件大小小于
-
分块上传:
- 初始化分块信息:不重试,因为可能此接口访问较快,没必要频繁生成
uploadId - 上传分块:重试3次
- 结束分块上传:重试3次,因为此时已经有了
uploadId,服务端应该保存uploadId一段时间
- 初始化分块信息:不重试,因为可能此接口访问较快,没必要频繁生成
二、测试
测试目标:
- 测试分块上传在弱网环境下,是否能上传成功
- 测试分块上传与普通上传,不同文件上传时长
- 测试分块上传,不同分块大小,不同文件上传时长
测试数据支持:文件大小:50KB、100KB、500KB、1MB、3MB、5MB、10MB、20MB、50MB、100MB、300MB、500MB、1GB、2GB
默认分块上传处理:
- 分块大小
2MB - 一次
HTTP请求,传输 4块 - 超时时间:30s
// HTTP 请求头部如下
Resquest Headers
Content-Type: multipart/form-data;
x-seq-list: 0,1,2,3
x-block-origin-size: 4194304
x-block-list-checksum: 2347692459,3042692883,1507846630,3481308608
客户端使用 QNET 进行测试,其中一个参数如下:
弱网模拟环境:
服务端节点-北京
客户端:法国
弱网场景:断线重连(短)
网络类型:WI-FI
延迟:240~500ms
丢包率:7.09%
抖动方差:398