近年來,http網絡請求量日益添加,如下是httparchive統計,從2012-11-01到2016-09-01的請求數量和傳輸大小的趨勢圖:javascript
當前大部份客戶端&服務端架構的應用程序,都是用http/1.1鏈接的,現代瀏覽器與單個域最大鏈接數,都在4-6個左右,由上圖Total Requests數據,若是不用CDN分流,平均有20個左右的串行請求。
HTTP2 是1999年發佈http1.1後的一次重大的改進,在協議層面改善了以上問題,減小資源佔用,來,直接感覺一下差別:php
HTTP/2 is the future of the Web, and it is here!
這是 Akamai 公司創建的一個官方的演示,用以說明 HTTP/2 相比於以前的 HTTP/1.1 在性能上的大幅度提高。 同時請求 379 張圖片,從Load time 的對比能夠看出 HTTP/2 在速度上的優點。css
SPDY 系列協議由谷歌開發,於 2009 年公開。它的設計目標是下降 50% 的頁面加載時間。當下不少著名的互聯網公司都在本身的網站或 APP 中採用了 SPDY 系列協議(當前最新版本是 SPDY/3.1),由於它對性能的提高是顯而易見的。主流的瀏覽器(谷歌、火狐、Opera)也都早已經支持 SPDY,它已經成爲了工業標準,HTTP Working-Group 最終決定以 SPDY/2 爲基礎,開發 HTTP/2。HTTP/2標準於2015年5月以RFC 7540正式發表。java
可是,HTTP/2 跟 SPDY 仍有不一樣的地方,主要是如下兩點:node
HTTP/2 支持明文 HTTP 傳輸,而 SPDY 強制使用 HTTPS
HTTP/2 消息頭的壓縮算法採用 HPACK ,而非 SPDY 採用的 DEFLATE(感謝網友 逸風之狐指正)git
協議文檔請見:rfc7540:HTTP2github
HTTP/2 採用二進制格式傳輸數據,而非 HTTP/1.x 的文本格式算法
由上圖能夠看到HTTP2在原來的應用層和HTTP層添加了一層二進制傳輸。chrome
二進制協議的一個好處是,能夠定義額外的幀。
HTTP/2 定義了近十種幀(詳情可分析抓包文件),爲未來的高級應用打好了基礎。若是使用文本實現這種功能,解析數據將會變得很是麻煩,二進制解析則方便得多。
RFC7540:Frame Definitions
協議中定義的幀
HTTP/2 複用TCP鏈接,在一個鏈接裏,客戶端和瀏覽器均可以同時發送多個請求或迴應,並且不用按照順序一一對應,這樣就避免了"隊頭堵塞"(見TCP/IP詳解卷一)。
每一個 Frame Header 都有一個 Stream ID 就是被用於實現該特性。每次請求/響應使用不一樣的 Stream ID。就像同一個 TCP 連接上的數據包經過 IP: PORT 來區分出數據包去往哪裏同樣。
rfc7540: HTTP2 Multiplexing中對Multiplexing的說明
Streams and Multiplexing A "stream" is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection. Streams have several important characteristics: o A single HTTP/2 connection can contain multiple concurrently open streams, with either endpoint interleaving frames from multiple streams. o Streams can be established and used unilaterally or shared by either the client or server. o Streams can be closed by either endpoint. o The order in which frames are sent on a stream is significant. Recipients process frames in the order they are received. In particular, the order of HEADERS and DATA frames is semantically significant. o Streams are identified by an integer. Stream identifiers are assigned to streams by the endpoint initiating the stream.
數據流發送到一半的時候,客戶端和服務器均可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的惟一方法,就是關閉TCP鏈接。這就是說,HTTP/2 能夠取消某一次請求,同時保證TCP鏈接還打開着,能夠被其餘請求使用。
HTTP/2 對消息頭採用 HPACK 進行壓縮傳輸,可以節省消息頭佔用的網絡的流量。而 HTTP/1.x 每次請求,都會攜帶大量冗餘頭信息,浪費了不少帶寬資源。
HTTP2對http頭創建索引表,相同的頭只發送hash table 的index, 同時還用了霍夫曼編碼和傳統的gzip壓縮。
服務端可以更快的把資源推送給客戶端。例如服務端能夠主動把 JS 和 CSS 文件推送給客戶端,而不須要客戶端解析 HTML 再發送這些請求。當客戶端須要的時候,它已經在客戶端了。
那麼存在一個問題,若是客戶端設置了緩存怎麼辦。有三種方式(來自社區)
cache-digest(提案)
HTTP2容許瀏覽器指定資源的優先級。
主流瀏覽器都只支持 HTTP/2 Over TLS
node中能夠用spdy模塊來啓動應用,spdy的api,與https是一致的且主流瀏覽器只支持HTTP/2 Over TLS,須要配置 私鑰和證書,本地自簽名服務器配置可參考引用6,7。
const express = require('express'); const fs = require('fs'); const http2 = require('spdy'); const path = require('path'); const options = { key: fs.readFileSync('./keys/privatekey.pem'), cert: fs.readFileSync('./keys/certificate.pem') }; const app = new express(); http2 .createServer(options, app) .listen(8080, ()=>{ console.log(`Server is listening on https://localhost:8080. You can open the URL in the browser.`) } ) app.use("/",(req,res)=>{ res.send("hello http2!"); })
如上,對於已存在的項目只要修改幾行代碼就可使用http2.0了。
請求頭和響應頭:
說明:新版的Chrome,對不安全的證書(如本地的自簽名服務)會降級到http1.1,firefox不會出現此問題。
啓動server push
app.get("/",(req,res)=>{ var stream = res.push('/app.js', { //服務器推送 status: 200, // optional method: 'GET', // optional request: { accept: '*/*' }, response: { 'content-type': 'application/javascript' } }) stream.on('error', function() { }) stream.end('console.log("http2 push stream, by Lucien ");') res.send(`hello http2! <script src="/app.js"></script>`);//express 並無host static ,這個app.js 來自push })
響應
能夠用chrome 內部自帶的工具(chrome://net-internals/)查看http2流量,但這個包信息量比較少,結構不如咱們熟悉的Fiddler or Wireshark清晰。
Fiddler是直接做爲中間代理,能夠做爲客戶端直接與服務端通信,能夠像瀏覽器那樣直接解密https,直接看到https報文,
可是因爲受限於.NET Framework暫不支持Http2.
用wireshark直接抓包 https:443端口的流量是這樣的:
數據被加密了,協議細節徹底看不到。
這裏介紹了一種方法獲取私鑰解包。
抓包https包時要把代理關了,否則私鑰不是同一個,wireshark不能解包(被這個坑了兩小時T T)。
一個包內有多個不一樣的Steam ID
追蹤解密後TCP流能夠看到,因爲多路複用,各個不一樣的請求交替傳輸不一樣的幀,因此流數據是亂的。但在同一幀內數據仍是正常的。
最後,HTTP2有更高的傳輸速度,更少的資源佔用,能夠去除各類性能優化tricks(如css sprite,inline-image.)
轉向WEB開發的美好將來T.T