歡迎關注個人我的公衆號,不按期更新本身的工做心得。
javascript
影響一個網絡請求的因素主要有兩個,帶寬和延遲。今天的網絡基礎建設已經使得帶寬獲得極大的提高,大部分時候都是延遲在影響響應速度。java
鏈接沒法複用會致使每次請求都經歷三次握手和慢啓動。三次握手在高延遲的場景下影響較明顯,慢啓動則對文件類大請求影響較大。node
head of line blocking會致使帶寬沒法被充分利用,以及後續健康請求被阻塞。git
HTTP1.0 -> HTTP1.1github
不過pipelining並非救世主,它也存在很多缺陷:npm
pipelining只能適用於http1.1,通常來講,支持http1.1的server都要求支持pipelining瀏覽器
只有冪等的請求(GET,HEAD)能使用pipelining,非冪等請求好比POST不能使用,由於請求之間可能會存在前後依賴關係。服務器
head of line blocking並無徹底獲得解決,server的response仍是要求依次返回,遵循FIFO(first in first out)原則。也就是說若是請求1的response沒有回來,2,3,4,5的response也不會被送回來。網絡
絕大部分的http代理服務器不支持pipelining。tcp
和不支持pipelining的老服務器協商有問題。
可能會致使新的Front of queue blocking問題。
多路複用經過多個請求stream共享一個tcp鏈接的方式,解決了http1.x holb(head of line blocking)的問題,下降了延遲同時提升了帶寬的利用率。
HTTP/2.0規定了在客戶端和服務器端會使用而且維護「首部表」來跟蹤和存儲以前發送的鍵值對,對於相同的頭部,沒必要再經過請求發送,只需發送一次。
事實上,若是請求中不包含首部(例如對同一資源的輪詢請求),那麼首部開銷就是零字節。此時全部首部都自動使用以前請求發送的首部。
若是首部發生變化了,那麼只須要發送變化了數據在Headers幀裏面,新增或修改的首部幀會被追加到「首部表」。首部表在 HTTP2.0的鏈接存續期內始終存在,由客戶端和服務器共同漸進地更新。
在應用層與傳輸層之間增長一個二進制分幀層,以此達到「在不改動HTTP的語義,HTTP 方法、狀態碼、URI及首部字段的狀況下,突破HTTP1.1的性能限制,改進傳輸性能,實現低延遲和高吞吐量。」
在二進制分幀層上,HTTP2.0會將全部傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼,其中HTTP1.x的首部信息會被封裝到Headers幀,而咱們的request body則封裝到Data幀裏面。
客戶端和服務器能夠把HTTP消息分解爲互不依賴的幀,而後亂序發送,最後再在另外一端把它們從新組合起來。注意,同一連接上有多個不一樣方向的數據流在傳輸。客戶端能夠一邊亂序發送stream,也能夠一邊接收者服務器的響應,而服務器那端同理。
多路複用致使全部資源都是並行發送,那麼就須要「優先級」的概念了,這樣就能夠對重要的文件進行先傳輸,加速頁面的渲染。
服務器推送是指在客戶端請求以前發送數據的機制。
另外有一點值得注意的是,客戶端若是退出某個業務場景,出於流量或者其它因素須要取消server push,也能夠經過發送RST_STREAM類型的frame來作到。
這裏使用 Node.js 做爲服務器端語言。
若是想要在生產環境中使用HTTP2,那麼你能夠去這裏生成一個證書。
若是你僅僅開發環境使用,那麼咱們能夠本身生成一個自簽名的TSL證書。
安裝OpenSSH
使用OpenSSH生成私鑰
openssl genrsa -des3 -passout pass:1234 -out server.pass.key 2048`
這裏 1234
爲私鑰密碼,若是你不想使用密碼,則能夠去除私鑰密碼,敲入以下密令:
openssl rsa -passin pass:x -in server.pass.key -out server.key
建立 證書籤名請求
這裏使用無密碼私鑰,若是使用帶密碼私鑰,只需將server.key
更換爲server.pass.key
便可,密令以下
openssl req -new -key server.key -out server.csr
建立證書
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
經過以上四個步驟,咱們獲得了三個文件
server.key 你的TSL證書私鑰
server.csr 你的TSL證書籤名請求
server.crt 你的TSL證書
安裝 node-http2 模塊
npm install http2
建立服務器
var options = { key: fs.readFileSync('./server.key'), cert: fs.readFileSync('./server.crt') }; require('http2').createServer(options, function(request, response) { response.end('Hello world!'); }).listen(8080);
啓動服務器
node index.js
使用瀏覽器訪問
http://localhost:8080
到此,一個簡單的Demo就完成了。
點擊這裏訪問完整Demo
https://github.com/zhanyouwei...
經過上面兩張截圖能夠發現,使用了HTTP2後,一樣的請求,在數據傳輸大小與速度上都有很是大的提高,幾乎能夠預見,不久的未來,HTTP2將會大放異彩。