HTTP/2 特性的簡單總結

小皮草發表於2019-03-07

有些地方後續補充完整

HTTP/1 的問題

1. 隊頭阻塞

HTTP/1 有個特性叫管道化(pipelining),允許一次傳送一組請求,但是隻能按照傳送順序依次接受。

因此,如果某個請求應答出現狀況,那麼剩下的工作都會被阻塞在那次請求應答之後,即隊頭阻塞。它會阻礙網路傳輸和 Web 頁面渲染。

目前措施:現代瀏覽器會針對單個域名開啟 6 個連線,通過各個連線分別傳送請求。(某種程度上的並行)

2. 低效的 TCP 利用

HTTP/1 並不支援多路複用,所以瀏覽器一般會針對指定域名開啟 6 個併發連線,這意味著擁塞視窗波動也會並行發生 6 次。TCP 協議保證那些連線都能正常工作,但是不能保證它們的效能上最優的。

3. 臃腫的訊息首部

雖然 HTTP/1 提供了壓縮被請求內容的機制,但是訊息首部卻無法壓縮

4. 受限的優先順序設定

5. 第三方資源

HTTP/2

大致分為兩部分:

  • 分幀層,即 h2 多路複用能力的核心部分;
  • 資料或 http 層

特性

  • 二進位制協議

    h2 的分幀層是基於幀的二進位制協議。

  • 首部壓縮

  • 多路複用

  • 加密傳輸

HTTP/2 是基於幀的協議,採用分幀是為了將重要資訊都封裝起來,讓協議的解析方可以輕鬆閱讀、解析並還原資訊。

HTTP/1 不是基於幀的,而是以文字分隔的。問題:

  • 速度慢且容易出錯
  • 一次只能處理一個請求或響應,完成之前不能停止解析
  • 無法預判解析需要多少記憶體

有了幀,處理協議的程式能預先知道會收到什麼。(因為幀會有固定的位元組去表達資訊)

幀結構

前 9 個位元組對於每個幀是一致的。(通過讀取這些位元組,可以準確知道在整個幀中期望的位元組數)

幀的英文是 frame,在我的理解有一種結構體的意思,相對於基於文字的要有結構有規律一些

名稱(幀欄位) 長度 描述
Length 3 位元組 表示幀負載的長度
Type 1 位元組 當前幀型別
Flags 1 位元組 具體幀型別的標識
R 1 bit 保留位,不要設定
Stream Identifier 31 bit 每個流的唯一 ID
Frame Payload 長度可變 真實的幀內容,長度在 Length 欄位設定
名稱(幀型別) ID 描述
DATA 0x0 傳輸流的核心內容
HEADERS 0x1 包含 HTTP 首部
PRIORITY 0x2 指示或者更改流的優先順序和依賴
RST_STREAM 0x3 允許一端停止流
SETTINGS 0x4 協商連線級引數
PUSH_PROMISE 0x5· 提示客戶端,伺服器要推送些東西
PING 0x6 測試連結可用性和往返時延(RTT)
GOAWAY 0x7 告訴另一端,當前端已結束
WINDOW_UPDATE 0x8 協商一端將要接受多少位元組(用於流量控制)
CONTINUATION 0x9 用以擴充套件 HEADER 資料塊

優勢

h1 由於是依靠分隔符的,因此只能處理完一個請求或響應,才能處理下一個;h2 是分幀的,所以請求和響應可以交錯甚至多路複用。

(個人理解就是,h1 中多個請求或者響應連線在一起,由於只是靠分隔符解析,因此無法判斷是多個內容連線起來的;而 h2 中多個幀連線在一起,由於幀更像個結構體,並且有長度資訊,解析程式能夠知道解析到哪裡算一個幀的結束。)

定義:HTTP/2 連線上獨立的、雙向的幀序列交換。

如果客戶端想要發出請求,它會開啟一個新的流,然後伺服器將在這個流上回復。

**因為有分幀,所以多個請求和響應可以交錯,而不會互相阻塞。**流 ID 用來標識幀所屬的流。

服務端推送

推送使伺服器能夠主動將物件發給客戶端。

首部壓縮

HPACK 是種表查詢壓縮方案,利用霍夫曼編碼獲得接近 GZIP 的壓縮率。

參考

  1. 《HTTP/2 基礎教程》

相關文章