已知http的請求響應是一對一的. 就是一個請求跟着接下來的響應便是與之配對了.
而另一種方式, 可以依靠順序, 即發送多個http請求, 然后返回對個http響應. 嚴格按照順序將他們對應起來, 稱為管道化鏈接.
但是由於有很多問題, 支持的都不好. 實際應用應該也是比較少的.
轉發一篇如下:
原文地址: http://www.yanglicalm.com/2017/02/12/%E7%AE%A1%E9%81%93%E5%8C%96%E8%BF%9E%E6%8E%A5/
其實一切都是由管道化連接而起,這是一個比較有意思的連接方式。
HTTP/1.1 允許在持久連接上可選的使用請求管道
。這是相對於keep-alive
連接的又一性能優化。在相應到達之前,可以將多條請求放入隊列,當第一條請求發往服務器的時候,第二第三條請求也可以開始發送了,在高延時網絡條件下,這樣做可以降低網絡的環回時間,提高性能。
- 如果客戶端無法確認連接是持久的,就不應該使用管道
- 必須按照與請求相同的順序回送HTTP響應,因為HTTP報文中是沒有序列號的,所以如果收到的響應失序了,就沒辦法將其與請求匹配起來
- HTTP客戶端必須做好連接會在任意時刻關閉的准備,還要准備好重發所有未完成的管道化請求
- HTTP客戶端不應該用管道化的方式發送回產生副作用的請求,比如
POST
請求。
管線化在iOS中的應用
在WWDC 2012 session 706 - Networking Best Practices中,Apple的工程師介紹了管線化的概念,我們知道了在NSMutableRequest
有個屬性叫做HTTPShouldUsePipelining
,標示是否開啟管線化連接,但是奇怪的是,這個值默認是NO
,按說如此強勢的功能為什么要設置為NO
呢,下面我們來看看。
通過上面的介紹我們會發現,客戶端接收響應的順序必須和發出的請求順序相同,也就是說這依賴於服務器對於相應的排序,那么問題來了,如果服務器不支持管線化的話,那么響應就會亂序,造成意想不到的問題,有幾個很出名的bug:
但是有件事情是很讓我困惑的,我在閱讀SDWebImage
源碼的時候,在SDWebImageDownloader
類中將HTTPShouldUsePipelining
設置為了YES
,不知道為什么沒有問題,希望有了解的大神可以給個解答。
除了上述的問題之外,管線化連接還是有性能問題的:
- 這篇文章從安全角度指出了管線化連接的問題,並且談到了一些特定情況下的性能損失。
- 這篇文章測試了幾個主流的瀏覽器,給出了管線化連接的性能並不是一直都是取勝的。
- WWDC 2015 - Networking with NSURLSession詳細解釋了一種叫做
Head of line blocking
的問題,是管線化連接的巨大瓶頸
Head of line blocking
來解釋下這個概念,翻譯成中文是線頭阻塞
。我們知道,管線化是把多個HTTP請求放到一個TCP連接中一一發送,而在發送過程中不需要等待服務器對前一個請求的響應,只不過,客戶端還是要按照發送請求的順序來接收響應,也就是說,如果第一個請求耗費了服務器很多的處理時間,那么后面的請求都要等待第一個處理完,也就出現了線頭阻塞。
目前,直到HTTP/1.0都沒有好的方法來解決這個問題,未來的HTTP/2.0或者SPDY中的異步操作才能解決這個問題
以上三篇,是關於HTTP連接的管理。