你了解HTTP2 0嗎?

2021-09-11 14:12:30 字數 2846 閱讀 3536

作為乙隻前端開發?,http是我們知識地圖裡面必不可少的一部分,也是面試必問知識點。http2號稱可以讓我們的應用更快、更簡單、更穩定,它完美解決了1.1版本的諸多問題,本文和大家一起聊聊http2的改進點。

正式講http2之前我們先講一下http的發展史。

現在我們先不聊http2, 看一下http發展到1.1存在有哪些問題:

線頭阻塞:tcp連線上只能傳送乙個請求,前面的請求未完成前,後續的請求都在排隊等待。

多個tcp連線

雖然http/1.1管線化可以支援請求併發,但是瀏覽器很難實現,chrome、firefox等都禁用了管線化。所以1.1版本請求併發依賴於多個tcp連線,建立tcp連線成本很高,還會存在慢啟動的問題。

頭部冗餘,採用文字格式

http/1.x版本是採用文字格式,首部未壓縮,而且每乙個請求都會帶上cookie、user-agent等完全相同的首部。

客戶端需要主動請求

先來乙個demo感受一下吊炸天的http/2.0,這個demo是載入379張,來對比http/1.1和http/2.0的效能。 http/1.1 與2.0 效能比較

理論上http/2.0會比http/1.1有一倍多的效能提公升,弱網環境下,效能提公升會更加明顯。 下面兩張圖是我在設定網路在fast 3g 和slow 3g的效能對比。

是不是被http/2.0的速度亮瞎了雙眼?2333,接下來我們正式開始聊聊2.0。看看2.0 相比與1.1的一些重大改進。

http2效能提公升的核心就在於二進位制分幀層。http2是二進位制協議,他採用二進位制格式傳輸資料而不是1.x的文字格式。

看圖吧!很清晰的表達了http/1.1的響應和2.0的區別。1.1響應是文字格式,而2.0把響應劃分成了兩個幀,圖中的headers(首部)和data(訊息負載) 是幀的型別。

這裡我們來提三個概念。

上面提到http/1.1的線頭阻塞和多個tcp連線的問題,http2的多路復用完美解決。http2讓所有的通訊都在乙個tcp連線上完成,真正實現了請求的併發。我們來看一下http2具體是怎麼實現的:

http2建立乙個tcp連線,乙個連線上面可以有任意多個流(stream),訊息分割成乙個或多個幀在流裡面傳輸。幀傳輸過去以後,再進行重組,形成乙個完整的請求或響應。這使得所有的請求或響應都無法阻塞。 我們再來回看上面的那個demo:

開啟控制台可以看到,http/1.1的方式,後面的的載入時間主要耗時在stalled,stalled的意思是從tcp連線建立完成,到真正可以傳輸資料之間的時間差。這就是隊頭阻塞,前面的請求沒有處理,後面的請求都在排隊等待。

這裡例子我們能很直觀的看到就是多路復用起到的優化作用。因為http2 實現了請求併發,後面的請求不用再等待,載入時長當然少了很多。截一張http2的載入耗時詳情來看看(要看比較靠後的請求):

咦??什麼情況?我們發現後面的很多請求依舊有在排隊哎,只是排隊的時間相對1.1少了很多。乙個tcp連線可以有任意數量的流,也就是同時可以併發任意數量的請求啊,為啥還會排隊呢?原因就是請求太多時,瀏覽器或伺服器會受不了,這超出了它的處理能力。流控制幫我們解決了這個問題,流控制會管理資料的傳輸,允許接收者停止或減少傳送的資料量,免得接收方不堪重負。所以請求太多時,還是會存在排隊等待的問題,因為不管是客戶端或伺服器端,能同時處理請求或響應都是有限的。

頭部壓縮也是http2的一大亮點。在1.x版本中,首部用文字格式傳輸,通常會給每個傳輸增加500-800位元組的開銷。現在開啟乙個網頁上百個請求已是常態,而每個請求帶的一些首部欄位都是相同的,例如cookie、user-agent等。http2為此採用hpack壓縮格式來壓縮首部。頭部壓縮需要在瀏覽器和伺服器端之間:

http2的靜態字典是長這個樣子的(只擷取了部分,完整**在這裡):

所以我們在傳輸首部欄位的時候,例如要傳輸method:get,那我們只需要傳輸靜態字典裡面method:get對應的索引值就可以了,乙個位元組搞定。像user-agent、cookie這種靜態字典裡面只有首部名稱而沒有值的首部,第一次傳輸需要user-agent在靜態字典中的索引以及他的值,值會採用靜態huffman編碼來減小體積。

第一次傳輸過user-agent 之後呢,瀏覽器和伺服器端就會把它新增到自己的動態字典中。後續傳輸就可以傳輸索引了,乙個位元組搞定。

我們用wireshark來抓包驗證一下:

http2目前都是https的請求,wireshark對https**抓包解密請參考這裡。

由於第一次傳輸的時候,字典裡面並沒有user-agent的值,這時候user-agent是63位元組,第二次傳輸時,他已經在動態字典裡面了,只傳索引,乙個位元組搞定。

header解碼後的長度有471個位元組,而headers流只有246個位元組。這只是第乙個請求,後續的請求壓縮力度會更大,因為前面請求用到的首部(靜態字典中沒有的)會新增到動態字典中,使得後續請求只需要傳輸字典裡面的索引。

伺服器端推送使得伺服器可以**客戶端需要的資源,主動推送到客戶端。

例如:客戶端請求index.html,伺服器端能夠額外推送script.js和style.css。 實現原理就是客戶端發出頁面請求時,伺服器端能夠分析這個頁面所依賴的其他資源,主動推送到客戶端的快取,當客戶端收到原始網頁的請求時,它需要的資源已經位於快取。

針對每乙個希望傳送的資源,伺服器會傳送乙個push_promise幀,客戶端可以通過傳送rst_stream幀來拒絕推送(當資源已經位於快取)。這一步的操作先於父響應(index.html),客戶端了解到伺服器端打算推送哪些資源,就不會再為這些資源建立重複請求。當客戶端收到index.html的響應時,script.js和style.css已經位於快取。

想要搭乙個http2伺服器的話推薦node,很簡單。鏈結

簡單講了http2相比1.1版本的重要改進點,感受了一下h2的強大。還有一些流優先化等特性文中未涉及,感興趣的可以在參考文章中看看。如有錯誤,懇請指正!

HTTP 2 0 協議詳解

無需 作者修改任何內容 把部署複雜性降至最低,無需變更網路基礎設施 與開源社群合作開發這個新協議 收集真實性能資料,驗證這個實驗性協議是否有效。解決 http 中的 隊首阻塞 問題 並行操作無需與伺服器建立多個連線,從而改進 tcp 的利用率,特別是擁塞控制方面 保持 http 1.1 的語義,利用...

快速入門http2 0

自 想要了解乙個事物,首先就要知道它是什麼。簡單來說,http 2 超文字傳輸協議第2版,最初命名為http2.0 是http協議的第二個主要版本。http 2是http協議自1999年http1.1發布後的首個更新,主要基於spdy協議。http2.0的特點是 在不改動http語義 方法 狀態碼 ...

HTTP 2 0 的那些事

spdy協議是google提出的基於傳輸控制協議 tcp 的應用層協議,通過壓縮 多路復用和優先順序來縮短載入時間。該協議是一種更加快速的內容傳輸協議,於2009 年年中發布。也可以把spdy看作是http 2的前身。spdy並不是首字母縮略字,而僅僅是 speedy 的縮寫。spdy現為googl...