HTTP/2的理解

HTTP/2主要通過以下方法減少延遲,改進頁面的加載速度:

  • HTTP Header的壓縮,采用HPack算法。
  • HTTP/2的Server Push。
  • 請求的pipeline。
  • 修復在HTTP 1.x的隊頭阻塞問題。
  • 在單個TCP連接里多工復用請求。

HTTP/2 頭部壓縮(HPack)

使用HPack算法壓縮HTTP/2的頭部,下面簡單介紹Hpack的工作原理:

簡單說,HTTP頭壓縮需要在HTTP/2客戶端和服務端之間:

  • 維護一份相同的靜態(tài)表(Static Table),包含常見的頭部名稱,和其鍵值對;
  • 維護一份相同的動態(tài)表(Dynamic Table),可以動態(tài)地添加內容;
  • 基于靜態(tài)哈夫曼碼表的哈夫曼編碼(Huffman Coding);

比如,在HTTP頭里,有些key:value是固定的:

:method: GET
:scheme: http

在編碼時,它們直接用一個index編號代替,例如:method:GET是2,這些在一個靜態(tài)表定義。靜態(tài)表的定義如下,總共61個Header Name,點擊URL https://tools.ietf.org/html/rfc7541#appendix-A查看所有靜態(tài)表的定義。
列出定義的部分鍵值對:

Index Header Name Header Value
1 :authority
2 :method GET
3 :method POST
4 :path /
5 :path /index.html
6 :scheme http
7 :scheme https
8 :status 200
... ... ...
32 cookie
... ... ...
60 via
61 www-authenticate

使用靜態(tài)表、動態(tài)表、以及Huffman編碼可以極大地提升壓縮效果。對于靜態(tài)表里的字段,原來需要N個字符表示的,現(xiàn)在只需要一個索引即可。對于靜態(tài)、動態(tài)表中不存在的內容,還可以使用哈夫曼編碼來減小體積。

HTTP/2的多路復用

HTTP/2定義了流(Stream)和幀(Frame)?;緟f(xié)議單元變小了,從消息(Message)變成了幀;流作為一種虛擬的通道,用來傳輸幀。與創(chuàng)建TCP連接相比,創(chuàng)建流的成本幾乎為零。基本協(xié)議單元的變小也大大提高了連接的利用效率。

HTTP 1.1 默認啟用長TCP連接,但所有的請求-響應都是按序進行的(這里的長連接可理解成半雙工協(xié)議。即便是HTTP 1.1引入了管道機制,也是如此)。復用同一個TCP連接期間,即便是通過管道同時發(fā)送了多個請求,服務端也是按請求的順序依次給出響應的;而客戶端在未收到之前所發(fā)出所有請求的響應之前,將會阻塞后面的請求(排隊等待),這稱為"隊頭堵塞"(Head-of-line blocking)。

HTTP/2復用TCP連接則不同,雖然依然遵循請求-響應模式,但客戶端發(fā)送多個請求和服務端給出多個響應的順序不受限制,這樣既避免了"隊頭堵塞",又能更快獲取響應。在復用同一個TCP連接時,服務器同時(或先后)收到了A、B兩個請求,先回應A請求,但由于處理過程非常耗時,于是就發(fā)送A請求已經處理好的部分, 接著回應B請求,完成后,再發(fā)送A請求剩下的部分。HTTP/2長連接可以理解成全雙工的協(xié)議。

一幅圖了解上面的描述:

HTTP/2的Server Push

HTTP/2與HTTP/1最大的不同之處在于,前者在后者的基礎上定義了流和幀,實現(xiàn)了多路復用。這是Server Push的基礎。

在HTTP 1.1里,在同一個 TCP 連接里面,上一個回應(response)發(fā)送完了,服務器才能發(fā)送下一個,但在HTTP/2里,可以將多個回應一起發(fā)送。

無PUSH模式

下圖是PUSH模式,當請求一個HTML時,如果HTML里有CSS文件,server會一并推給client,而不像在HTTP 1.1下,還需要再發(fā)一個CSS的請求。

PUSH模式

根據(jù)上圖,從理論上PUSH模式下性能會好很多。

舉個例子解釋一下。下面是一個簡單的HTML頁面,假說是index.html 。

<html>
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <p>This is a sample to illustrate how HTTP/2 works</p>
  <img src="example.png">
</body>
</html>

這里有三個文件需要處理:該HTML頁面、CSS文件style.css以及圖片example.png。在HTTP 1.1里為了處理這三個文件,Client需要發(fā)三個請求給Server。

首先,發(fā)送一個請求index.html。

GET /index.html HTTP/1.1

Client解析該HTML文件,繼而知道有2個style.css和example.png資源文件下載。

Client繼續(xù)發(fā)送2個請求下載他們。

GET /style.css  HTTP/1.1
GET /example.png  HTTP/1.1

如果使用HTTP/2的Server Push特征,根據(jù)上面的PUSH模式圖,我們可以看出,Server還沒有收到Client的請求,就把各種資源推送給Client。

拿上面例子繼續(xù)舉例,當Client只請求index.html,但是Server把index.html、style.cssexample.png全部發(fā)送給瀏覽器。這樣只需要一輪 HTTP 通信,Client就得到了全部資源。

參考

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

友情鏈接更多精彩內容