HTTP/2對比HTTP/1.1,新特性是什么?是如何解決隊頭阻塞與壓縮頭部的?
本文轉載自微信公眾號「三分鐘學前端」,作者sisterAn。轉載本文請聯系三分鐘學前端公眾號。
引言
本文主要通過以下四個方面介紹,循序漸進走進HTTP/2:
- HTTP/1.1發明以來發生了哪些變化?
- HTTP/1.1 協議的性能缺陷
- HTTP/2 新特性
- HTTP/2 遺留問題
HTTP/1.1發明以來發生了哪些變化?
近年來,如果你仔細觀察那些最流行的網站首頁所需要下載的資源的話,會發現一個非常明顯的趨勢:
- 消息變大 :從幾 KB 大小的消息,到幾 MB 大小的消息;
- 頁面資源變多 :從每個頁面不到 10 個的資源,到每頁超 100 多個資源;
- 內容形式變多樣 :從單純到文本內容,到圖片、視頻、音頻等內容;
- 實時性要求變高 :對頁面的實時性要求的應用越來越多;
正如下圖所示,從 2011 年以來, 傳輸數據大小與平均請求資源數量不斷持續增長,并沒有減緩的跡象(綠色:傳輸數據大小,紅色:平均請求資源數量):
自從 1997 年 HTTP/1.1 發布以來,我們已經使用 HTTP/1.x 相當長一段時間了,但近幾年內容的爆炸式成長使得 HTTP/1.1 越來越無法滿足現代網絡的需求了
HTTP/1.1 協議的性能缺陷
1. 高延遲:頁面訪問速度下降
雖然近幾年來網絡帶寬增長非常快,然而我們卻并沒有看到網絡延遲有對應程度的降低,這主要是由于隊頭阻塞 (Head-Of-Line Blocking)問題導致
HTTP/1.1 版引入了管道機制(pipelining),即在同一個TCP連接里面,客戶端可以同時發送多個請求,進一步改進了 HTTP 協議的效率
但這要求服務端必須按照請求發送的順序返回響應,當順序請求多個文件時,其中一個請求因為某種原因被阻塞時,在后面排隊的所有請求也一并被阻塞,這就是隊頭阻塞 (Head-Of-Line Blocking)
隊頭阻塞導致再打的帶寬無法被充分利用
因此 人們嘗試過以下辦法來解決隊頭阻塞問題:
- 使用多個域名 :將同一個頁面的資源分散到不同域名,提升并發連接上限,因為瀏覽器通常對同一域名的 HTTP 連接最大只能是 6 個
- 引入雪碧圖 :將多張小圖合并成一張大圖供瀏覽器 JavaScript 來切割使用,這樣可以將多個請求合并成一個請求,但是帶來了新的問題,當某張小圖片更新了,那么需要重新請求大圖片,浪費了大量的網絡帶寬;
- 將小圖內聯 :將圖片的二進制數據通過 base64 編碼后,把編碼數據嵌入到 HTML 或 CSS 文件中,以此來減少網絡請求次數;
- .icon {
- background: url(data:image/png;base64,<data>) no-repeat;
- }
使用 webpack 等工具打包 :打包壓縮多個 JavaScript 文件到一個文件中,以一個請求替代了很多個請求,但是帶來的問題,當某個 js 文件變化了,需要重新請求同一個包里的所有 js 文件;
按需加載 :來減少第一時間的 HTTP 請求次數
2. 明文傳輸:不安全
HTTP/1.1 在傳輸數據時,所有傳輸的內容都是明文,客戶端和服務器端都無法驗證對方的身份,這在一定程度上無法保證數據的安全性。
3. 無狀態:頭部巨大切重復
由于 HTTP 協議是無狀態的,每一個請求都得攜帶 HTTP 頭部,特別是對于有攜帶 cookie 的頭部,而 cookie 的大小通常很大,另外還有User Agent、Accept、Server等,通常多達幾百字節甚至上千字節,但 Body 卻經常只有幾十字節
4. 不支持服務器推送
HTTP/1.1 不支持服務器推送消息,因此當客戶端需要獲取通知時,只能通過定時器不斷地拉取消息,這無疑浪費大量了帶寬和服務器資源。
HTTP/2 新特性
在 HTTP/1.x 中,為了性能考慮,我們會引入雪碧圖、將小圖內聯、使用多個域名等等的方式,但還是有一些關鍵點無法優化,例如HTTP頭部巨大且重復、明文傳輸不安全、服務器不能主動推送等,要改變這些必須重新設計 HTTP 協議,于是 HTTP/2 就出來了!
2015 年,HTTP/2 發布。HTTP/2 是現行 HTTP 協議(HTTP/1.x)的替代,但它不是重寫,HTTP 方法 / 狀態碼 / 語義都與 HTTP/1.x 一樣。HTTP/2 基于 SPDY,專注于性能,最大的目標是在用戶和網站間只用一個連接(connec-tion)。
從目前的情況來看,國內外一些排名靠前的站點基本都實現了 HTTP/2 的部署,使用 HTTP/2 能帶來 20%~60% 的效率提升。
可以通過該鏈接直觀感受下 HTTP/2 比 HTTP/1 到底快了多少: https://http2.akamai.com/demo
1. 二進制傳輸
在不改動 HTTP/1.x 的語義、方法、狀態碼、URI 以及首部字段….. 的情況下,HTTP/2 是如何做到「突破 HTTP1.1 的性能限制,改進傳輸性能,實現低延遲和高吞吐量」的 ?
關鍵之一就是在應用層(HTTP/2)和傳輸層(TCP or UDP)之間增加一個二進制分幀層。
在二進制分幀層中, HTTP/2 會將所有傳輸的信息分割為更小的消息和幀(frame),并對它們采用二進制格式的編碼,其中 HTTP1.x 的首部信息會被封裝到 HEADERS 幀,而相應的 Request Body 則封裝到 DATA 幀里面,HTTP/2 數據分幀后,“Header+Body"的報文結構就完全消失了,協議看到的只是一個個"碎片”。
HTTP/2 中,同域名下所有通信都在單個連接上完成,該連接可以承載任意數量的雙向數據流。每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間可以亂序發送,根據幀首部的流標識可以重新組裝
2. Header 壓縮(HPACK)
HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。
HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發送同樣字段了,只發送索引號,這樣就提高速度了。
3. 多路復用
在 HTTP/2 中引入了多路復用的技術。多路復用很好地解決了瀏覽器限制同一個域名下請求數量的問題,同時也更容易實現全速傳輸,畢竟新開一個 TCP 連接都需要慢慢提升傳輸速度。
多路復用,就是在一個 TCP 連接中可以存在多條流。換句話說,也就是可以發送多個請求,對端可以通過幀中的標識知道屬于哪個請求。
這一特性使得 HTTP 傳輸性能得到極大提升,主要體現在以下三個方面:
多工
HTTP/2 復用 TCP 連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"
數據流
HTTP/2 并行交錯地發送多個請求 / 響應,請求 / 響應之間互不影響
因此,必須要對數據包做標記,指出它屬于哪個請求 / 響應。
HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬于哪個數據流。另外還規定,客戶端發出的數據流,ID一律為奇數,服務器發出的,ID為偶數。
數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。
優先級
在 HTTP/2 中,每個請求都可以帶一個 31bit 的優先值,0 表示最高優先級, 數值越大優先級越低。有了這個優先值,客戶端和服務器就可以在處理不同的流時采取不同的策略,以最優的方式發送流、消息和幀。
4. 服務端 Push
HTTP/2 允許服務器未經請求,主動向客戶端發送資源,這叫做服務器推送(server push)。
常見場景是客戶端請求一個網頁,這個網頁里面包含很多靜態資源。正常情況下,客戶端必須收到網頁后,解析HTML源碼,發現有靜態資源,再發出靜態資源請求。其實,服務器可以預期到客戶端請求網頁后,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。
這樣就可以相對減少一點延遲時間。當然在瀏覽器兼容的情況下你也可以使用 prefetch 。
注意: 服務端可以主動推送,客戶端也可以主動選擇是否接收,如果服務端推送的資源已經被瀏覽器緩存過,瀏覽器可以通過發送 RST_STREAM 幀來拒收,另外,主動推送也遵守同源策略
5. 提高安全性
出于兼容的考慮,HTTP/2 延續了 HTTP/1 的“明文”特點,可以像以前一樣使用明文傳輸數據,不強制使用加密通信,但 HTTPS 已經是大勢所趨,各大主流瀏覽器都公開宣布只支持加密的 HTTP/2,所以,真實應用中的 HTTP/2 是還是加密的:
HTTP/2 遺留問題
HTTP/2 還會隊頭阻塞嗎?
HTTP/2 也存在隊頭阻塞問題,比如丟包。
如果造成隊頭阻塞,問題可能比http1.1還嚴重,因為只有一個tcp連接,后續的傳輸都要等前面,http/1.1 多個tcp連接,阻塞一個,其他的還可以正常跑
HTTP/2下還會擁塞嗎?
由于 TCP 連接減少而使網絡擁塞狀況得以改觀;
慢啟動時間減少,擁塞和丟包恢復速度更快。
參考
解密 HTTP/2 與 HTTP/3 的新特性:https://www.infoq.cn/article/ku4okqr8vh123a8dlccj