URLSession在LTE、5G网络下多次下载后带宽使用受限问题
问题根因
URLSession.shared全局共享实例的默认连接池配置针对蜂窝网络做了限制,短时间发起大量小文件短连接时,200次请求后连接池占满,后续请求需要排队等待空闲连接,直接表现为下载速度骤降- iOS系统对单个App在蜂窝网络下的可用临时端口数量做了限制,高频短连接会快速耗尽端口资源,后续请求需要等待TIME_WAIT状态的端口回收,该限制在WiFi环境下阈值更高,因此不会触发问题
- 运营商核心网针对蜂窝网络下的高频短连接存在隐性的连接调度策略,虽然不会直接限速,但会增加后续TCP握手的延迟,叠加客户端侧的连接排队问题放大了速度下降的表现,独立测速时因为是单连接大流量请求,不会触发该调度策略,因此测速结果正常
可行修复方案
- 替换全局共享会话,自行创建自定义配置的URLSession实例:
let downloadConfig = URLSessionConfiguration.default // 调整单Host最大连接数,蜂窝网下建议设置为10~15即可 downloadConfig.httpMaximumConnectionsPerHost = 12 // 开启移动网络下的连接空闲保活优化 downloadConfig.shouldUseExtendedBackgroundIdleMode = true // 合理调整超时时间,避免无效请求长期占用连接 downloadConfig.timeoutIntervalForRequest = 20 downloadConfig.timeoutIntervalForResource = 45 // 允许使用蜂窝/计费网络 downloadConfig.allowsCellularAccess = true downloadConfig.allowsExpensiveNetworkAccess = true // 用自定义配置创建专属下载会话,不要复用shared实例 let downloadSession = URLSession(configuration: downloadConfig, delegate: self, delegateQueue: OperationQueue())
- 控制下载并发数,不要同时发起超过5个下载任务,待现有任务完成后再推入新的任务,避免短时间占满连接池和端口资源
- 有后端配合条件的情况下,建议将10~20个小文件打包为单个压缩包下载,大幅减少短连接数量,从根源降低资源消耗
- 每完成100~150次下载任务后,调用当前会话的
finishTasksAndInvalidate()方法销毁旧会话,重新创建新的下载会话,主动释放内部缓存和占用的端口资源
内容的提问来源于stack exchange,提问作者Michael Jajou
相关产品推荐
相关产品推荐

