背景 近年來,http網(wǎng)絡(luò)請求量日益添加,以下是httparchive統(tǒng)計(jì),從2012-11-01到2016-09-01的請求數(shù)量和傳輸大小的趨勢圖: 當(dāng)前大部份客戶端&服務(wù)端架構(gòu)的應(yīng)用程序,都是用http/1.1連接的,現(xiàn)代瀏覽器與單個域最大連接數(shù),都在4-6個左右,由上圖Total Requests數(shù)據(jù),如果不用CDN分流,平均有20個左右的串行請求。 HTTP2 是1999年發(fā)布http1.1后的一次重大的改進(jìn),在協(xié)議層面改善了以上問題,減少資源占用,來,直接感受一下差異: HTTP/2 is the future of the Web, and it is here! 這是 Akamai 公司建立的一個官方的演示,用以說明 HTTP/2 相比于之前的 HTTP/1.1 在性能上的大幅度提升。 同時請求 379 張圖片,從Load time 的對比可以看出 HTTP/2 在速度上的優(yōu)勢。 本文所有源碼和抓包文件在github(https://github.com/etoah/note/tree/master/http2) HTTP/2 源自 SPDY/2 SPDY 系列協(xié)議由谷歌開發(fā),于 2009 年公開。它的設(shè)計(jì)目標(biāo)是降低 50% 的頁面加載時間。當(dāng)下很多著名的互聯(lián)網(wǎng)公司都在自己的網(wǎng)站或 APP 中采用了 SPDY 系列協(xié)議(當(dāng)前最新版本是 SPDY/3.1),因?yàn)樗鼘π阅艿奶嵘秋@而易見的。主流的瀏覽器(谷歌、火狐、Opera)也都早已經(jīng)支持 SPDY,它已經(jīng)成為了工業(yè)標(biāo)準(zhǔn),HTTP Working-Group 最終決定以 SPDY/2 為基礎(chǔ),開發(fā) HTTP/2。HTTP/2標(biāo)準(zhǔn)于2015年5月以RFC 7540正式發(fā)表。 但是,HTTP/2 跟 SPDY 仍有不同的地方,主要是以下兩點(diǎn): HTTP/2 支持明文 HTTP 傳輸,而 SPDY 強(qiáng)制使用 HTTPS HTTP/2 消息頭的壓縮算法采用 HPACK ,而非 SPDY 采用的 DEFLATE(感謝網(wǎng)友 逸風(fēng)之狐指正)
HTTP2特性概覽 1. 二進(jìn)制協(xié)議 HTTP/2 采用二進(jìn)制格式傳輸數(shù)據(jù),而非 HTTP/1.x 的文本格式 由上圖可以看到HTTP2在原來的應(yīng)用層和HTTP層添加了一層二進(jìn)制傳輸。 二進(jìn)制協(xié)議的一個好處是,可以定義額外的幀。 HTTP/2 定義了近十種幀(詳情可分析抓包文件),為將來的高級應(yīng)用打好了基礎(chǔ)。如果使用文本實(shí)現(xiàn)這種功能,解析數(shù)據(jù)將會變得非常麻煩,二進(jìn)制解析則方便得多。 RFC7540:Frame Definitions 協(xié)議中定義的幀 2. 多路復(fù)用 HTTP/2 復(fù)用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發(fā)送多個請求或回應(yīng),而且不用按照順序一一對應(yīng),這樣就避免了”隊(duì)頭堵塞”(見TCP/IP詳解卷一)。 每個 Frame Header 都有一個 Stream ID 就是被用于實(shí)現(xiàn)該特性。每次請求/響應(yīng)使用不同的 Stream ID。就像同一個 TCP 鏈接上的數(shù)據(jù)包通過 IP: PORT 來區(qū)分出數(shù)據(jù)包去往哪里一樣。 rfc7540: HTTP2 Multiplexing中對Multiplexing的說明
3. 數(shù)據(jù)流 數(shù)據(jù)流發(fā)送到一半的時候,客戶端和服務(wù)器都可以發(fā)送信號(RST_STREAM幀),取消這個數(shù)據(jù)流。1.1版取消數(shù)據(jù)流的唯一方法,就是關(guān)閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。 4. 頭信息壓縮: HTTP/2 對消息頭采用 HPACK 進(jìn)行壓縮傳輸,能夠節(jié)省消息頭占用的網(wǎng)絡(luò)的流量。而 HTTP/1.x 每次請求,都會攜帶大量冗余頭信息,浪費(fèi)了很多帶寬資源。 HTTP2對http頭建立索引表,相同的頭只發(fā)送hash table 的index, 同時還用了霍夫曼編碼和傳統(tǒng)的gzip壓縮。 5. 服務(wù)器推送 服務(wù)端能夠更快的把資源推送給客戶端。例如服務(wù)端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 再發(fā)送這些請求。當(dāng)客戶端需要的時候,它已經(jīng)在客戶端了。 那么存在一個問題,如果客戶端設(shè)置了緩存怎么辦。有三種方式(來自社區(qū)) 客戶端可以通過設(shè)置SETTINGS_ENABLE_PUSH為0值通知服務(wù)器端禁用推送 發(fā)現(xiàn)緩存后,客戶端和服務(wù)器都可以發(fā)送信號(RST_STREAM幀),取消這個數(shù)據(jù)流。 cache-digest(提案) rfc7540: HTTP2 Server Push 6. 流優(yōu)先級 HTTP2允許瀏覽器指定資源的優(yōu)先級。 rfc7540: Stream Priority 瀏覽器支持 主流瀏覽器都只支持 HTTP/2 Over TLS node中啟用http2 node中可以用spdy模塊來啟動應(yīng)用,spdy的api,與https是一致的且主流瀏覽器只支持HTTP/2 Over TLS,需要配置 私鑰和證書,本地自簽名服務(wù)器配置可參考引用6,7。
如上,對于已存在的項(xiàng)目只要修改幾行代碼就可以使用http2.0了。 請求頭和響應(yīng)頭: 說明:新版的Chrome,對不安全的證書(如本地的自簽名服務(wù))會降級到http1.1,firefox不會出現(xiàn)此問題。 啟動server push
響應(yīng) 抓包分析 可以用chrome 內(nèi)部自帶的工具(chrome://net-internals/)查看http2流量,但這個包信息量比較少,結(jié)構(gòu)不如我們熟悉的Fiddler or Wireshark清晰。 Fiddler是直接作為中間代理,可以作為客戶端直接與服務(wù)端通訊,可以像瀏覽器那樣直接解密https,直接看到https報文, 但是由于受限于.NET Framework暫不支持Http2. 用wireshark直接抓包 https:443端口的流量是這樣的: 數(shù)據(jù)被加密了,協(xié)議細(xì)節(jié)完全看不到。 這里介紹了一種方法獲取私鑰解包。 抓包https包時要把代理關(guān)了,不然私鑰不是同一個,wireshark不能解包(被這個坑了兩小時T T)。 一個包內(nèi)有多個不同的Steam ID 追蹤解密后TCP流可以看到,由于多路復(fù)用,各個不同的請求交替?zhèn)鬏敳煌膸?,所以流?shù)據(jù)是亂的。但在同一幀內(nèi)數(shù)據(jù)還是正常的。 最后 最后,HTTP2有更高的傳輸速度,更少的資源占用,可以去除各種性能優(yōu)化tricks(如css sprite,inline-image.) 轉(zhuǎn)向WEB開發(fā)的美好未來T.T 參考資料
關(guān)注「前端大全」 看更多精選前端技術(shù)文章 ↓↓↓
|
|
來自: 昵稱37315817 > 《待分類》