iOS并發(fā)網絡請求排隊造成下載超時錯誤

項目中因為一些歷史原因,有著大量的并發(fā)下載。在一次體驗優(yōu)化的過程中我們對AFNetworking設置了

    [request setTimeoutInterval:10];

認為一個連接如果發(fā)起10s后還未開始,變認為超時,顯示錯誤提示。

然而不久后我們發(fā)現當進行大量并發(fā)小文件下載的時候,會刷出一批批的請求超時

Error Domain=NSURLErrorDomain Code=-1001 "請求超時。" UserInfo={NSUnderlyingError=0x1c0450230 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=xxxxxx.zip, NSErrorFailingURLKey=https://xxxxxx.zip, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=請求超時。}

一開始毫無頭緒,因為網絡肯定是正常的,那為什么會請求超時呢。

項目中有引入FLEX,借助FLEX我們看了一下超時前成功的請求的狀態(tài)


image.png

發(fā)現一個請求在排隊花費的時間遠大于請求的時間,而且接近了10s

看來原因就在……排隊。

看timeoutInterval的描述

/*! 
    @abstract Sets the timeout interval of the receiver.
    @discussion The timeout interval specifies the limit on the idle
    interval allotted to a request in the process of loading. The "idle
    interval" is defined as the period of time that has passed since the
    last instance of load activity occurred for a request that is in the
    process of loading. Hence, when an instance of load activity occurs
    (e.g. bytes are received from the network for a request), the idle
    interval for a request is reset to 0. If the idle interval ever
    becomes greater than or equal to the timeout interval, the request
    is considered to have timed out. This timeout interval is measured
    in seconds.
*/

如果一個請求排隊時間超過了10s,即使不是因為弱網造成的也會被判定為超時。

那為什么會排隊呢?

查看 NSURLSessionConfiguration 中的HTTPMaximumConnectionsPerHost屬性描述可以看到:

The maximum number of simultaneous connections to make to a given host.
This property determines the maximum number of simultaneous connections made to each host by tasks within sessions based on this configuration.
This limit is per session, so if you use multiple sessions, your app as a whole may exceed this limit. Additionally, depending on your connection to the Internet, a session may use a lower limit than the one you specify.
The default value is 6 in macOS, or 4 in iOS.

可以看到在一個urlsession中對同一個host只允許4個并發(fā)連接,超過4個遍會進入排隊。排隊導致后續(xù)任務超時。

測試了http在keep alive開關下的情況
設置timeout時間1s 發(fā)起200個連接
keepalive開啟 成功100個左右
keepalive關閉 成功50個不到

猜測

  • 成功數變化是由于keep alive導致連接時變化引起的
  • 成功數變化是由于keep alive下一個connection包括了多個task?

于是解決辦法很簡單,增大HTTPMaximumConnectionsPerHost或者延長超時時間。但是為什么蘋果要做出這個默認限制(默認值還這么低)呢?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容