談談網路協議 – HTTP/V2/V3
阿新 • • 發佈:2021-08-16
HTTP協議的不足
- 同一時間,一個連線只能對應一個請求
- 針對同一個域名,大多數瀏覽器允許同時最多6個併發連線
- 只允許客戶端主動發起請求
- 一個請求只能對應一個響應
- 同一個會話的多次請求中,頭資訊會被重複傳輸
- 通常會給每個傳輸增加500~800位元組的開銷
- 如果使用 Cookie,增加的開銷有時會達到上千位元組
SPDY
- SPDY(speedy的縮寫),是基於TCP的應用層協議,它強制要求使用SSL/TLS
- 2009年11月,Google宣佈將SPDY作為提高網路速度的內部專案
- SPDY與HTTP的關係
- SPDY並不用於取代HTTP,它只是修改了HTTP請求與響應的傳輸方式
- 只需增加一個SPDY層,現有的所有服務端應用均不用做任何修改
- SPDY是HTTP/2的前身
- 2015年9月,Google宣佈移除對SPDY的支援,擁抱HTTP/2
HTTP/2
- HTTP/2,於2015年5月以RFC 7540正式發表
- 根據W3Techs的資料,截至2019年6月,全球有36.5%的網站支援了HTTP/2
- HTTP/1.1和HTTP/2速度對比
- HTTP/2在底層傳輸做了很多的改進和優化,但在語意上完全與HTTP/1.1相容
- 比如請求方法(如GET、POST)、Status Code、各種Headers等都沒有改變
- 因此,要想升級到HTTP/2
- 開發者不需要修改任何程式碼
- 只需要升級伺服器配置、升級瀏覽器
特性 - 二進位制格式
- HTTP/2採用二進位制格式傳輸資料,而非HTTP/1.1的文字格式
- 二進位制格式在協議的解析和優化擴充套件上帶來更多的優勢和可能
一些基本概念
- 資料流:已建立的連線內的雙向位元組流,可以承載一條或多條訊息
- 所有通訊都在一個TCP連線上完成,此連線可以承載任意數量的雙向資料流
- 訊息:與邏輯HTTP請求或響應訊息對應,由一系列幀組成
- 幀:HTTP/2通訊的最小單位,每個幀都包含幀頭(會標識出當前幀所屬的資料流)
- 來自不同資料流的幀可以交錯傳送,然後再根據每個幀頭的資料流識別符號重新組裝
特性 - 多路複用( Multiplexing)
- 客戶端和伺服器可以將 HTTP訊息分解為互不依賴的幀,然後交錯傳送,最後再在另一端把它們重新組裝起來
- 並行交錯地傳送多個請求,請求之間互不影響
- 並行交錯地傳送多個響應,響應之間互不干擾
- 使用一個連線並行傳送多個請求和響應
- 不必再為繞過HTTP/1.1限制而做很多工作
- 比如image sprites、合併CSS\JS、內嵌CSS\JS\Base64圖片、域名分片等
- 因為它都是在同一個TCP連線中請求的,不會消耗建立連結花費的時間
特性 - 優先順序
- HTTP/2 標準允許每個資料流都有一個關聯的權重和依賴關係
- 可以向每個資料流分配一個介於1至256之間的整數
- 每個資料流與其他資料流之間可以存在顯式依賴關係
- 客戶端可以構建和傳遞“優先順序樹”,表明它傾向於如何接收響應
- 伺服器可以使用此資訊通過控制CPU、記憶體和其他資源的分配設定資料流處理的優先順序
- 在資源資料可用之後,確保將高優先順序響應以最優方式傳輸至客戶端
-
應儘可能先給父資料流分配資源
-
同級資料流(共享相同父項)應按其權重比例分配資源
① A、B依賴於隱式“根資料流”,A獲得的資源比例是12/16,B獲得的資源比例是4/16
② D依賴於根資料流,C依賴於D,D應先於C獲得完整資源分配
③ D應先於C獲得完整資源分配,C應先於A和B獲得完整資源分配,B獲得的資源是A所獲資源的1/3
④ D應先於E和C獲得完整資源分配,E和C應先於A和B獲得相同的資源分配,B獲得的資源是A所獲資源的1/3
特性 - 頭部壓縮
- HTTP/2使用HPACK壓縮請求頭和響應頭
- 可以極大減少頭部開銷,進而提高效能
- 早期版本的HTTP/2和SPDY使用 zlib壓縮
- 可以將所傳輸頭資料的大小減小85%~88%
- 但在2012年夏天,被攻擊導致會話劫持
- 後被更安全的HPACK取代
- 如上圖,它並不是不傳那些欄位了,而是有一張彙總的頭部表,重複只傳陣列索引值
特性 - 伺服器推送( Server Push)
- 伺服器可以對一個客戶端請求傳送多個響應
- 除了對最初請求的響應外,伺服器還可以向客戶端推送額外資源,而無需客戶端額外明確地請求
- 注意:主動推送說的並不是伺服器一開始可以主動推送,而是客戶端發起請求後
問題 - 隊頭阻塞( head of line blocking)
- 當多個流都發送到客戶端,但頭部的那個流丟包了,或者遲遲不到,客戶端就需要等待這個流到了後才會去渲染,如果一直不來,那就一直等待,超時後會重傳
- 資料是有順序的,傳送的時候的順序 和 接收後組裝的順序要一樣
解決方案:QUIC 協議(後面的 HTTP/3)
- 它能實現如果丟包了,可以先提取已經接收到的包
- 然後再單獨去重發丟失的那個包
問題 - 握手延遲
- RTT(Round Trip Time):往返時延,可以簡單理解為通訊一來一回的時間
- 上圖可以看出 TCP + TLS 的握手時長是 200 到 300 ms
- QUIC 幾乎為0,因為它走的是UDP協議,不需要管對方是否已經收到
HTTP/3
- Google覺得HTTP/2仍然不夠快,於是就有了HTTP/3
- HTTP/3由Google開發,棄用TCP協議,改為使用基於UDP協議的QUIC協議實現
- QUIC(Quick UDP Internet Connections),譯為:快速UDP網路連線,由Google開發,在2013年實現
- 於2018年從HTTP-over-QUIC改為HTTP/3
HTTP/3 - 疑問
- HTTP/3基於UDP,如何保證可靠傳輸?
- 由QUIC來保證
- 為何Google不開發一個新的不同於TCP、UDP的傳輸層協議?
- 目前世界上的網路裝置基本只認TCP、UDP
- 如果要修改傳輸層,意味著作業系統的核心也要修改
- 另外,由IETF標準化的許多TCP新特性都因缺乏廣泛支援而沒有得到廣泛的部署或使用
- 因此,要想開發並應用一個新的傳輸層協議,是極其困難的一件事情
特性 - 連線遷移
- TCP基於4要素(源IP、源埠、目標IP、目標埠)
- 切換網路時至少會有一個要素髮生變化,導致連線發生變化
- 當連線發生變化時,如果還使用原來的TCP連線,則會導致連線失敗,就得等原來的連線超時後重新建立連線
- 所以我們有時候發現切換到一個新網路時,即使新網路狀況良好,但內容還是需要載入很久
- 如果實現得好,當檢測到網路變化時立刻建立新的TCP連線,即使這樣,建立新的連線還是需要幾百毫秒的時間
- QUIC的連線不受4要素的影響,當4要素髮生變化時,原連線依然維持
- QUIC連線不以4要素作為標識,而是使用一組Connection ID(連線ID)來標識一個連線
- 即使IP或者埠發生變化,只要Connection ID沒有變化,那麼連線依然可以維持
- 比如
- 當裝置連線到Wi-Fi時,將進行中的下載從蜂窩網路連線轉移到更快速的Wi-Fi連線
- 當Wi-Fi連線不再可用時,將連線轉移到蜂窩網路連線
問題 - 作業系統核心、CPU負載
- 據Google和Facebook稱,與基於TLS的HTTP/2相比,它們大規模部署的QUIC需要近2倍的CPU使用量
- Linux核心的UDP部分沒有得到像TCP那樣的優化,因為傳統上沒有使用UDP進行如此高速的資訊傳輸
- TCP和TLS有硬體加速,而這對於UDP很罕見,對於QUIC則基本不存在
- 隨著時間的推移,相信這個問題會逐步得到改善
作者:悠悠清風
出處:https://www.ywgao.cn/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
我的聯絡方式:[email protected]