天天看點

http2相關協定詳解(express中開啟http2流程)

最近想玩點新花樣,是以就想搞下http2,之前公司也有搞過go語言的,一直對https和http2比較好奇,就錘了下。

http2.0與1.1的性能對比這裡有個從别人那裡抄來的demo位址,上面分别使用和http1.1和http2來加載較大量的圖檔請求,差不多400個圖檔,http2的傳輸速度差不多是http1.1的2-4倍,極大地減少了網絡的延遲。

http2曆史及相關技術

2009年,谷歌公開了自行研發的 SPDY 協定,作為http2的前身他瞄準http1.x的痛點:高延遲,原因有2個

1.浏覽器阻塞(HOL blocking):浏覽器會因為一些原因阻塞請求。浏覽器對于同一個域名一般同時隻能有4-6 個連接配接(下面盜了一個圖),超過浏覽器最大連接配接數限制,後續請求就會被阻塞,這個被稱作線頭阻塞head of line block。

http2相關協定詳解(express中開啟http2流程)

2.建立連接配接(Initial connection):HTTP 是基于 TCP 協定的,浏覽器最快也要在第三次握手時才能捎帶 HTTP 請求封包,達到真正的建立連接配接,但是這些連接配接無法複用會導緻每次請求都經曆三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對檔案類大請求影響較大

spdy被當作 HTTP/2 的基礎,有不少改進(可以不看,我抄的)

1:降低延遲,針對HTTP高延遲的問題,SPDY優雅的采取了多路複用(multiplexing)。多路複用通過多個請求stream共享一個tcp連接配接的方式,解決了線頭阻塞的問題,降低了延遲同時提高了帶寬的使用率。

2.請求優先級(request prioritization)。多路複用帶來一個新的問題是,在連接配接共享的基礎之上有可能會導緻關鍵請求被阻塞。SPDY允許給每個request設定優先級,這樣重要的請求就會優先得到響應。比如浏覽器加載首頁,首頁的html内容應該優先展示,之後才是各種靜态資源檔案,腳本檔案等加載,這樣可以保證使用者能第一時間看到網頁内容。

3.header壓縮。使用了Hpack壓縮算法可以減小http的大小和數量。

4.基于HTTPS的加密協定傳輸,大大提高了傳輸資料的可靠性。

5.服務端推送(server push),采用了SPDY的網頁,例如我的網頁有一個sytle.css的請求,在用戶端收到sytle.css資料的同時,服務端會将sytle.js的檔案推送給用戶端,當用戶端再次嘗試擷取sytle.js時就可以直接從緩存中擷取到,不用再發請求了。

http2新特性

1.新的二進制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本協定的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多。基于這種考慮HTTP2.0的協定解析決定在 應用層(HTTP/2)和傳輸層(TCP or UDP)之間采用二進制格式,實作友善且健壯。在 應用層(HTTP/2)和傳輸層(TCP or UDP)之間。

2.多路複用(MultiPlexing),即連接配接共享,即每一個request都是是用作連接配接共享機制的。一個request對應一個id,這樣一個連接配接上可以有多個request,每個連接配接的request可以随機的混雜在一起,接收方可以根據request的 id将request再歸屬到各自不同的服務端請求裡面。單連結是的記憶體更少,吞吐量變大。

http2相關協定詳解(express中開啟http2流程)

3.header壓縮,HTTP1.x的header帶有大量資訊,而且每次都要重複發送,HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重複header的傳輸,又減小了需要傳輸的大小。SPDY/2使用的是gzip壓縮算法,但後來出現的兩種攻擊方式BREACH和CRIME使得即使走ssl的SPDY也可以被破解内容,最後綜合考慮采用的是一種叫HPACK的壓縮算法。這兩個漏洞和相關算法可以點選連結檢視更多的細節,不過這種漏洞主要存在于浏覽器端,因為需要通過javascript來注入内容并觀察payload的變化。

4.服務端推送(server push),同SPDY一樣,HTTP2.0也具有server push功能。目前,有大多數網站已經啟用HTTP2.0,例如YouTuBe,淘寶網等網站,利用chrome控制台可以檢視是否啟用H2:

Linux生成證書

linux中輸入下列代碼,如果openssl不能使用的話,安裝下,這裡我就不搞了,我用的是xx雲
[root]#  openssl genrsa -des3 -passout pass:x -out server.pass.key  
[root]#  openssl rsa -passin pass:x -in server.pass.key -out server.key 
    writing RSA key 
[root]#  openssl req -new -key server.key -out server.csr 
    // 國家名CN
    Country Name ( letter code) [AU]:CN 
    // 省,我江蘇的
    State or Province Name (full name) [Some-State]:Jiangsu
    // 城市
    Locality Name (eg, city): suzhou
    // 下面回車到底,可以不填
[root]#  openssl x509 -req -sha256 -days  -in server.csr -signkey server.key -out server.crt 
           

産生了三個檔案

server.crt

server.csr

server.key

EXPRESS代碼

express腳手架

安裝http2相關庫執行npm install sdpy –save-dev

//生成一個express項目
//在bin/www頭部加上
const http2 = require('spdy'),
        fs = require('fs');

//把上面linux生成的幾個檔案放到該項目的key檔案夾裡
//var server = http.createServer(app);上面加一個options讀取兩個驗證檔案
const options = {
    key: fs.readFileSync('./key/server.key'),
    cert: fs.readFileSync('./key/server.crt')
}
//var server = http.createServer(app);替換成下面這個
const server = http2.createServer(options, app);
           

然後打開https://localhost:3000,這個service下的檔案都是http2的了,在浏覽器裡檢視,如果為h2就是開啟成功了,如果浏覽器裡沒有Protocol就右鍵點上面,然後勾選

http2相關協定詳解(express中開啟http2流程)

HTTP/2.0 相比1.0有哪些重大改進?

HTTP,HTTP2.0,SPDY,HTTPS你應該知道的一些事

關于請求被挂起頁面加載緩慢問題的追查

浏覽器允許的并發請求資源數是什麼意思?

繼續閱讀