作者:林冠巨集 / 指尖下的幽靈
GitHub : github.com/af913337456…
超文字傳輸協議 HTTP 的 2.0 版本的協議在 2015 年的時候已經發布了。相比於前面的 HTTP 1.1 版本。它多出了下面三個主要的新特性。
- 在建立連線後,可以
多路複用
- 在建立連線後,一次的請求與被響應,視為
流
- 資料傳輸分為
二進位制幀
片段
HTTP 2.0 對 HTTP 的延遲問題起到了可以說是一個巨大的優化。下面的連結是網上的一個直觀網站,它展示了同樣是 300 多張圖片,分別在 HTTP 1.1 和 HTTP 2.0 協議下載入的耗時。HTTP 2.0 的速度差不多是 HTTP 1.1 的6倍。
下面我們來直觀地認識下它們。
首先是二進位制幀
在 TCP 協議中,資料的傳輸單位是資料包
。資料分成兩大部分。頭部(header) 和 實際資料部分(body)。
在 HTTP 2.0 中,它把資料包的兩大部分分成了 header frame
和 data frame
。也就是頭部幀和資料體幀。幀的傳輸最終在流中進行,流中的幀,頭部(header)幀
和 data 幀
可以分為多個片段幀,例如data
幀即是可以 data = data_1 + data_2 + ... + data_n
。
此外地,如果基於二進位制幀
整體來劃分,除了報文的幀分類。還有其它一些輔助幀型別,例如評論中提到的:SETTINGS、PING、GOWAY、WINDOW_UPDATE等控制幀。
其次是流
流
代表了一個完整的請求-響應
資料互動過程。它具有如下幾個特點:
- 雙向性:同一個流內,可同時傳送和接受資料。
- 有序性:流中被傳輸的資料就是
二進位制幀
。幀在流上的被髮送與被接收都是按照順序進行的。 - 並行性:流中的
二進位制幀
都是被並行傳輸的,無需按順序等待。但卻不會引起資料混亂,因為每個幀都有順序標號。它們最終會被按照順序標號來合併。 - 流的建立:流可以被客戶端或伺服器單方面建立, 使用或共享。
- 流的關閉:流也可以被任意一方關閉。
下圖來源於:https://blog.csdn.net/zqjflash/article/details/50179235
。它演示了流中的幀的有序性
與並行性
。例如資料包1
的 data frame
就沒有連著一起傳輸,而是分成了2個。
總結一下流和幀的關係
幀是流中的資料單位。一個資料包的header 幀可以分成多個 header 幀,data 幀可以分成多個data 幀。
多路複用
HTTP 2.0 的多路複用其實是 HTTP 1.1 中長連結的升級版本。
在 HTTP 1.1 中,一次連結成功後,只要該連結還沒斷開,那麼 client 端可以在這麼一個連結中有序地發起多個請求,並以此獲得每個請求對應的響應資料。它的缺點是,一次請求與響應的互動必須要等待前面的請求互動完成,否則後面的只能等待,這個就是線頭阻塞
。下面舉個例子:
請求A 和 請求B。A 先被髮起,此時 server 端接收到了 A 請求,正在處理。同時 B 請求也發過來了。但是 A 請求還沒被返回,此時 B 請求只能等待。
在 HTTP 2.0 中,一次連結成功後,只要連結還沒斷開,那麼 client 端就可以在一個連結中併發地
發起多個請求,每個請求及該請求的響應不需要等待其他的請求,某個請求任務耗時嚴重,不會影響到其它連線的正常執行。
下面通過圖來看看:
因為這上述這三個特性,讓 HTTP 2.0 在資料的傳輸延遲上,起到了很大的優化作用。
那麼,在我們的程式碼中,如何指定使用 HTTP 2.0 協議呢?
最簡單的方法,程式碼中,使用網路請求,在構造請求引數的時候,在 http 請求頭部指定 protocol 版本即可,例如下面例子:
http 1.1 的
GET /index HTTP/1.1
Host: www.xxx.com
複製程式碼
本文參考於: