HTTP 協議中的並發限制及隊首阻塞問題


本文轉載自HTTP 協議中的並發限制及隊首阻塞問題

串行連接

HTTP/0.9 和早期的 HTTP/1.0 協議對 HTTP 請求處理是串行化的。假如一個頁面包含 3 個樣式文件,同屬於一個協議、域名、端口。那么,瀏覽器一共需要發起四次請求,並且每次只能打開一個 TCP 通道,在一個請求資源完成下載后,立刻斷開該連接,再開啟一個新的連接去處理隊列中的下一個請求。隨着頁面資源大小、數量的不斷擴增,網絡延遲時間會不斷堆積,用戶會面對滿屏空白,等待過長時間而失去耐心。

img

並行連接

為了提高網絡的吞吐能力,改進后的 HTTP 協議允許客戶端同時打開多個 TCP 連接,並行地請求多個資源,充分利用帶寬。通常,每一個連接之間都會有一定延遲,但請求的傳輸時間是重疊的,總體上時延要比串行連接低很多。考慮到每一個連接都會消耗系統資源,並且服務器需要處理海量的用戶並發請求,瀏覽器會對並發請求數量做一定的限制。即使 RFC 並沒有規定具體的限制數量,各瀏覽器廠商也都會有自己的標准:

  • IE 7: 2
  • IE 8/9: 6
  • IE 10: 8
  • IE 11: 13
  • Firefox: 6
  • Chrome: 6
  • Safari: 6
  • Opera: 6
  • iOS WebView: 6
  • Android WebView: 6

img

持久連接(長連接)

早期的 HTTP 協議對每個請求都占用一個獨立的 TCP 連接,這無疑增加了 TCP 的建立連接開銷、擁塞控制開銷、釋放連接開銷,改進后的 HTTP/1.0 和 HTTP/1.1(默認)都支持了持久連接。如果一個請求完成后,不會立刻斷開連接,而是在一定的時間內保持連接,以便快速處理即將到來的 HTTP 請求,復用同一個 TCP 通道,直到客戶端心跳檢測失敗或服務器連接超時。這個特性可以通過 HTTP 首部 Connection: keep-alive 來激活,客戶端也可以發送 Connection: close 來主動關閉連接。所以,我們看到,並行連接和持久連接這兩種優化是相輔相成的,並行連接使得首次加載頁面可以同時打開多個 TCP 連接,而持久連接保證了后續的請求復用已打開的 TCP 連接,這也是現代 Web 頁面的普遍機制。

img

管道化連接

持久連接讓我們可以重用連接來完成多次請求,但它必須滿足 FIFO 的隊列順序,必須保證前一個請求成功到達服務器、處理成功並且收到服務器返回的首個字節,才可以發起隊列中下一個請求。HTTP 管道允許客戶端在同一個 TCP 通道內連續發起多個請求,而不必等待響應,消除了往返延遲時間差。但現實情況由於 HTTP/1.x 協議的限制,不允許數據在一個鏈路上交錯到達(IO 多路復用)。設想一種情況,客戶端服務器端同時發送一個 HTML 和多個 CSS 請求,服務器並行處理所有請求,當所有的 CSS 請求處理完成並加入到緩沖隊列,卻發現 HTML 請求處理遇到問題而無限被掛起,嚴重時甚至造成緩沖區溢出,這種情況就叫做隊首阻塞。因此,這個方案在 HTTP/1.x 協議中並沒有被采納。

img

隊首阻塞並不是 HTTP 中獨有的概念,而是在緩存式通信網絡交換中的一種普遍現象

總結

  1. 對於同一個協議、域名、端口,瀏覽器允許同時打開個 TCP 連接,一般上限為 6 個。
  2. 同一個 TCP 連接允許發起多次 HTTP 請求,但必須等待前一個請求的首個字節響應到達客戶端。
  3. 由於隊首阻塞問題,不允許客戶端同時發送隊列中所有請求,這個問題在 HTTP/2.0 得已解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM