一文讀懂 HTTP

今天,HTTP 1.1 已經變成互聯網中主要的協議。但是在 HTTP 協議誕生初期卻被認為是簡單直接的協議。1996 年在 RFC 1945 中定義了 HTTP 1.0 規範,僅 60 頁,到 1999 年在 RFC 2616 定義了 HTTP 1.1,增長到了 176 頁。但是,隨著 web 技術的飛速發展。 HTTP 1.1 已經無法滿足用戶對性能的要求,此後 Google 推出協議 SPDY,意在解決 HTTP 1.1 中廣為人知的性能問題。SPDY 得到了 Chrome、Firefox 和 Opera 的支持,很多大型網站(如谷歌、Twitter、Facebook)都對兼容客戶端使用 SPDY。SPDY 在被行業採用並證明能夠大幅提升性能之後,已經具備了成為一個標準的條件。

TTP/2 是 HTTP 協議自 1999 年 HTTP 1.1 發佈後的首個更新,主要基於 SPDY 協議。它由互聯網工程任務組(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小組進行開發。該組織於2014年12月將HTTP/2標準提議遞交至IESG進行討論,於2015年2月17日被批准。HTTP/2標準於2015年5月以RFC 7540正式發表。

那 HTTP /2 到底有哪些具體變化呢?

二進制分幀

先來理解幾個概念:

  • 幀(幀):HTTP/2數據通信的最小單位。
  • 消息(Message):指 HTTP/2 中邏輯上的 HTTP 消息。例如請求和響應等,消息由一個或多個幀組成。
  • 流(流):存在於連接中的一個虛擬通道。流可以承載雙向消息,每個流都有一個唯一的整數ID。

HTTP/2 採用二進制格式傳輸數據,而非 HTTP 1.x 的文本格式,二進制協議解析起來更高效。

HTTP/1 的請求和響應報文,都是由起始行,首部和實體正文(可選)組成,各部分之間以文本換行符分隔。HTTP/2 將請求和響應數據分割為更小的幀,並且它們採用二進制編碼。

HTTP/2 中,同域名下所有通信都在單個連接上完成(多路複用中介紹),這個連接可以承載任意數量的雙向數據流。每個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間可以亂序發送,因為根據幀首部的流標識可以重新組裝。

多路複用

多路複用,代替原來的序列和阻塞機制。所有就是請求的都是通過一個 TCP連接併發完成。 HTTP 1.x 中,如果想併發多個請求,必須使用多個 TCP 鏈接,且瀏覽器為了控制資源,還會對單個域名有 6-8 的個數限制,如下圖,紅色圈出來的請求就因域名鏈接數已超過限制,而被掛起等待了一段時間:

一文讀懂 HTTP/2 特性

在 HTTP/2 中,有了二進制分幀之後,HTTP/2 不再依賴 TCP 鏈接去實現多流並行了,在 HTTP/2中:

  • 同域名下所有通信都在單個連接上完成。
  • 單個連接可以承載任意數量的雙向數據流。
  • 數據流以消息的形式發送,而消息又由一個或多個幀組成,多個幀之間可以亂序發送,因為根據幀首部的流標識可以重新組裝。

這一特性,性能會有極大的提升,因為:

  • 同個域名只需要佔用一個 TCP 連接,消除了因多個 TCP 連接而帶來的延時和內存消耗。
  • 單個連接上可以並行交錯的請求和響應,之間互不干擾。
  • 在HTTP/2中,每個請求都可以帶一個31bit的優先值,0表示最高優先級, 數值越大優先級越低。有了這個優先值,客戶端和服務器就可以在處理不同的流時採取不同的策略,以最優的方式發送流、消息和幀。

服務器推送

服務端可以在發送頁面HTML時主動推送其它資源,而不用等到瀏覽器解析到相應位置,發起請求再響應。例如服務端可以主動把JS和CSS文件推送給客戶端,而不需要客戶端解析HTML再發送這些請求。服務端可以主動推送,客戶端也有權利選擇接收與否。如果服務端推送的資源已經被瀏覽器緩存過,瀏覽器可以通過發送RST_STREAM幀來拒收。主動推送也遵守同源策略,服務器不會隨便推送第三方資源給客戶端。

頭部壓縮

HTTP 1.1請求的大小變得越來越大,有時甚至會大於TCP窗口的初始大小,因為它們需要等待帶著ACK的響應回來以後才能繼續被髮送。HTTP/2對消息頭採用HPACK(專為http2頭部設計的壓縮格式)進行壓縮傳輸,能夠節省消息頭佔用的網絡的流量。而HTTP/1.x每次請求,都會攜帶大量冗餘頭信息,浪費了很多帶寬資源。

HTTP 每一次通信都會攜帶一組頭部,用於描述這次通信的的資源、瀏覽器屬性、cookie 等,例如

一文讀懂 HTTP/2 特性

為了減少這塊的開銷並提升性能, HTTP/2會壓縮這些首部:

  • HTTP/2在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發送的鍵-值對,對於相同的數據,不再通過每次請求和響應發送;
  • 首部表在HTTP/2的連接存續期內始終存在,由客戶端和服務器共同漸進地更新;
  • 每個新的首部鍵-值對要麼被追加到當前表的末尾,要麼替換表中之前的值。

例如:下圖中的兩個請求, 請求一發送了所有的頭部字段,第二個請求則只需要發送差異數據,這樣可以減少冗餘數據,降低開銷。

一文讀懂 HTTP/2 特性

我們來看一個實際的例子,下面是用WireShark抓取的訪問google首頁的包:

一文讀懂 HTTP/2 特性

上圖是是訪問https://www.google.com/抓到的第一個請求的頭部,可以看到頭部的內容,總共佔用了437 bytes,我們選中頭部的cookie,可以看到cookie總共佔用了118 bytes。接下來我們看看第二個請求的頭部:

一文讀懂 HTTP/2 特性

從上圖可以看到,得益於頭部壓縮,第二個請求中cookie只佔用了1個字節,我們來看看變化了的Accept字段:

一文讀懂 HTTP/2 特性

由於Accept字段與請求一中的內容不同,需要發送給服務器,所以佔用了29 bytes。

PS: 這裡有個akamai的HTTP /2 的演示鏈接,有興趣的可以點擊看看:https://http2.akamai.com/demo

一文讀懂 HTTP/2 特性

瀏覽器和網絡服務支持情況:http2支持清單

結語

又拍雲 CDN 當前已全平臺支持 HTTP/2,並已默認開啟。又因 HTTP/2 是在 HTTPS 協議的基礎上實現的,所以只要使用又拍雲 HTTPS 加速服務的域名,都可免費享受 HTTP/2 服務,無需做任何特殊配置。而開啟HTTPS,只需完成證書申請與管理,無須繁雜流程,輕鬆實現網站與 Web 應用的 HTTPS 加密部署。


分享到:


相關文章: