今天,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 在被行業採用並證實可以大幅提高性能以後,已經具有了成爲一個標準的條件。html
HTTP/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正式發表。git
先來理解幾個概念:github
HTTP/2 採用二進制格式傳輸數據,而非 HTTP 1.x 的文本格式,二進制協議解析起來更高效。 web
HTTP/1 的請求和響應報文,都是由起始行,首部和實體正文(可選)組成,各部分之間以文本換行符分隔。HTTP/2 將請求和響應數據分割爲更小的幀,而且它們採用二進制編碼。 瀏覽器
HTTP/2 中,同域名下全部通訊都在單個鏈接上完成(多路複用中介紹),這個鏈接能夠承載任意數量的雙向數據流。每一個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間能夠亂序發送,由於根據幀首部的流標識能夠從新組裝。緩存
多路複用,代替原來的序列和阻塞機制。全部就是請求的都是經過一個 TCP
鏈接併發完成。 HTTP 1.x 中,若是想併發多個請求,必須使用多個 TCP 連接,且瀏覽器爲了控制資源,還會對單個域名有 6-8 的個數限制,以下圖,紅色圈出來的請求就因域名連接數已超過限制,而被掛起等待了一段時間: 服務器
在 HTTP/2 中,有了二進制分幀以後,HTTP/2 再也不依賴 TCP 連接去實現多流並行了,在 HTTP/2中:cookie
同域名下全部通訊都在單個鏈接上完成。網絡
單個鏈接能夠承載任意數量的雙向數據流。併發
數據流以消息的形式發送,而消息又由一個或多個幀組成,多個幀之間能夠亂序發送,由於根據幀首部的流標識能夠從新組裝。
這一特性,性能會有極大的提高,由於:
同個域名只須要佔用一個 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的鏈接存續期內始終存在,由客戶端和服務器共同漸進地更新;
每一個新的首部鍵-值對要麼被追加到當前表的末尾,要麼替換表中以前的值。
例如:下圖中的兩個請求, 請求一發送了全部的頭部字段,第二個請求則只須要發送差別數據,這樣能夠減小冗餘數據,下降開銷。
咱們來看一個實際的例子,下面是用WireShark抓取的訪問google首頁的包:
上圖是是訪問https://www.google.com/抓到的第一個請求的頭部,能夠看到頭部的內容,總共佔用了437 bytes,咱們選中頭部的cookie,能夠看到cookie總共佔用了118 bytes。接下來咱們看看第二個請求的頭部:
從上圖能夠看到,得益於頭部壓縮,第二個請求中cookie只佔用了1個字節,咱們來看看變化了的Accept字段:
因爲Accept字段與請求一中的內容不一樣,須要發送給服務器,因此佔用了29 bytes。
PS: 這裏有個akamai的HTTP /2 的演示連接,有興趣的能夠點擊看看:https://http2.akamai.com/demo
瀏覽器和網絡服務支持狀況:http2支持清單
又拍雲 CDN 當前已全平臺支持 HTTP/2,並已默認開啓。又因 HTTP/2 是在 HTTPS 協議的基礎上實現的,因此只要使用又拍雲 HTTPS 加速服務的域名,均可免費享受 HTTP/2 服務,無需作任何特殊配置。而開啓HTTPS,只需完成證書申請與管理,無須繁雜流程,輕鬆實現網站與 Web 應用的 HTTPS 加密部署。
參考資料:
Jerry Qu blog 中的HTTP/2專題;
維基百科:HTTP/2
RFC 7540 – 超文本傳輸協議第2版(HTTP / 2)
FC 7541 – HPACK:HTTP / 2的頭壓縮:http://httpwg.org/specs/rfc7541.html
http2講解:https://ye11ow.gitbooks.io/http2-explained/content/part2.html
附:
瀏覽器和網絡服務支持狀況:http2支持清單
HTTP/2 和 HTTP/1 速度對比:HTTP/2: the Future of the Internet
爲何非全站升級HTTPS不可?https://zhuanlan.zhihu.com/p/26953410