HTTP2簡介
HTTP2是對HTTP1.1的升級,對HTTP1.1性能問題進行了優化,主要從以下兩個方面來優化:
1、頭部壓縮
HTTP1.1主要是對Body進行壓縮,而頭部卻沒有壓縮,HTTP2通過HPACK演算法對頭部進行壓縮,減少了傳輸時間,
2、隊頭阻塞
HTTP1.1使用的是TCP協議,并且為了節省資源,采用了長連接,長連接引入了隊頭阻塞的問題,HTTP2引入了流和幀,解決了HTTP層面上的隊頭阻塞,
HTTP2報文結構詳解
1、二進制 替換 文本
HTTP1.1采用的是文本描述,也就是通過ASCII文本進行傳輸,采用文本描述的好處是除錯程式方便,能夠直接看出資料包中的資料情況,
而HTTP2使用的二進制來進行傳輸,用01串來描述資料,除錯和查看資料的具體含義就不填方便了,但是這種二進制傳輸計算機決議方便,體積小,性能高,
舉個例子,比如之前需要傳遞對應的文本值來表示對應的選擇,而二進制通過二進制編碼就能知道編碼對應的選擇,一個二進制編碼對應著一個文本值, 一個二進制編碼肯定比文本占用的空間小,
2、HTTP2將HTTP1中資料包分解為了幀
將HTTP1.1的資料包分為HEADERS幀和DATA幀,屬于是化整為零,為的就是多路復用,具體原理我們下邊再說,


HTTP2連接程序
連接前言
當TCP三次握手成功后,客戶端需要向服務器發送一個連接前言,
連接前言是一個HTTP1.1報文,是一個ASCII文本,里面記錄著一個magic字串,當服務器接收到這個請求后,服務器就知道客戶端想要使用HTTP2協議,
頭部壓縮
確定了HTTP2連接后,就開始準備發送HTTP2請求了,
首先就是發送HEADERS 幀,
HTTP1.1中對Body進行GZIP等壓縮方式,但是對于頭部卻沒有采取任何辦法,
HTTP2采用了 HPACK 演算法來壓縮,HPACK 中客戶端和服務器都要維護一個索引表,

如上圖所示,索引表中維護了頭部中Key-Value的對應關系和索引下標,
到時候,HTTP2請求中頭部不用再發送Key-Value了,直接發送對應的索引下標就可以了,
上述的索引表是一個靜態的表,記錄著常用的頭欄位,HTTP的起始行中記錄了Method、StatusCode等資訊,也被記錄到了索引表中,
有的HTTP2頭部有著特殊的頭部欄位,所以HPACK又在靜態表的尾部開始維護一個動態記錄,當第一次發送索引表中不存在的Key-Value的時候,會使用實際資料發送,客戶端和服務器對應的索引表會對其快取,等到下一次發送的時候,就可以直接發送索引下標了,
所以說,HTTP2通過HPACK演算法,將每次發送Key-Value替換成了發送一個下標,極大的減少了HTTP2頭部的資料量,傳輸效率極大的提高了,
二進制幀
HTTP2將之前的head+body的一個資料包分為了 HEADER幀 和 若干個 DATA幀
格式如下圖所示:

1、幀長度
幀的總長度,應用程式按照長度來讀取
2、幀型別
HTTP2中有 資料幀、控制幀等類別,控制幀有著更高的傳輸優先權
3、標志位
8個bit,可以代表8個狀態,比如END_HEADERS代表是否頭資料傳輸結束、END_STREAM表示單方面傳輸資料結束
4、流識別符號
幀屬于哪個流,每個HTTP包傳輸都是一個虛擬流,通過流識別符號才能將前后發送的幀重組為一個完整的資料包,
5、實際傳輸的資料
HTTP2發送程序
HTTP2利用幀+流的方式解決了HTTP1中的隊頭阻塞問題,
HTTP1中每個HTTP包復用一個TCP連接,每次只能等到前一個HTTP回應后才能發送后一個HTTP請求,如果前一個HTTP回應阻塞的話,后面的HTTP請求都會跟著阻塞,這就是隊頭阻塞問題,
HTTP2也是利用的長連接,多個HTTP請求復用一個TCP連接,
但是HTTP2將每個HTTP請求都看作一個流,將HTTP資料包分解為多個幀,包括HEADER幀和DATA幀,每個幀都對應著一個流標識號,
多個HTTP請求之間的發送是亂序的,但是每個HTTP請求中的幀的發送是有序的,
雖然多個HTTP請求之間的發送請求是亂序的,但是可以基于流識別符號來進行重組,一個流識別符號對應著一個HTTP請求,
流識別符號不能復用,是自動遞增的,客戶端使用的是奇數,服務器使用的偶數,
這就解決了隊頭阻塞問題,


轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/302207.html
標籤:其他
上一篇:HTTPS優化
