標籤:伺服器的響應 修改 world 頭部 頻寬 返回 加速 一個 訊息
影響一個網路請求的因素主要有兩個,頻寬和延遲。今天的網路基礎建設已經使得頻寬得到極大的提升,大部分時候都是延遲在影響響應速度。串連無法複用
串連無法複用會導致每次請求都經曆三向交握和慢啟動。三向交握在高延遲的情境下影響較明顯,慢啟動則對檔案類大請求影響較大。head of line blocking
head of line blocking會導致頻寬無法被充分利用,以及後續健康請求被阻塞。
HTTP1.0 -> HTTP1.1
不過pipelining並不是救世主,它也存在不少缺陷:
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也不會被送回來。
絕大部分的httpProxy 伺服器不支援pipelining。
和不支援pipelining的老伺服器協商有問題。
可能會導致新的Front of queue blocking問題。
HTTP2 VS HTTP1.1多工
多工通過多個請求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來做到。HTTP2 實踐
這裡使用 Node.js 作為伺服器端語言。1. 產生TLS認證
如果想要在生產環境中使用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認證
2. 使用Node.js 建立伺服器
安裝 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源碼下載
點擊這裡訪問完整Demo
https://github.com/zhanyouwei...測試結果對比
通過上面兩張可以發現,使用了HTTP2後,同樣的請求,在資料轉送大小與速度上都有非常大的提升,幾乎可以預見,不久的將來,HTTP2將會大放異彩。
HTTP2.0 原理詳解