哎呀,一不小心自己的博客也是HTTP/2.0了,前段時間對網站進行了https遷移並上了CDN,最終的結果是這醬紫的(重點小綠鎖,安全標示以及HTTP/2.0請求)。 科普 隨著互聯網的快速發展,HTTP1.x協議得到了迅猛發展,但當網站一個頁麵包含了數幾十個請求時,HTTP1.x協議的局限性便暴露 ...
哎呀,一不小心自己的博客也是HTTP/2.0了,前段時間對網站進行了https遷移並上了CDN,最終的結果是這醬紫的(重點小綠鎖,安全標示以及HTTP/2.0請求)。
科普
隨著互聯網的快速發展,HTTP1.x協議得到了迅猛發展,但當網站一個頁麵包含了數幾十個請求時,HTTP1.x協議的局限性便暴露了出來:
- 每個請求與響應需要單獨建立鏈路進行請求(Connection欄位能夠解決部分問題),浪費資源。
- 每個請求與響應都需要添加完整的頭信息,應用數據傳輸效率較低。
- 預設沒有進行加密,數據在傳輸過程中容易被監聽與篡改。
HTTP/2 協議於 2015 年 5 月 14 日正式版發佈。HTTP2正是為瞭解決HTTP1.x暴露出來的問題而誕生的。
說到HTTP2不得不提spdy。
由於HTTP1.x暴露出來的問題,Google設計了全新的名為spdy的新協議。spdy在五層協議棧的TCP層與HTTP層引入了一個新的邏輯層以提高效率。spdy是一個中間層,對TCP層與HTTP層有很好的相容,不需要修改HTTP層即可改善應用數據傳輸速度。
spdy通過多路復用技術,使客戶端與伺服器只需要保持一條鏈接即可併發多次數據交互,提高了通信效率。
而HTTP2便士基於spdy的思路開發的。
通過流與幀概念的引入,繼承了spdy的多路復用,並增加了一些實用特性。
HTTP2有什麼特性呢?HTTP2的特性不僅解決了上述已暴露的問題,還有一些功能使HTTP協議更加好用。
多路復用
利用多路復用可以實現延遲削減。
每個 Frame Header 都有一個 Stream ID 就是被用於實現該特性。每次請求/響應使用不同的 Stream ID。就像同一個 TCP 鏈接上的數據包通過 IP:PORT來區分出數據包去往哪裡一樣。通過 Stream ID 標識,所有的請求和響應都可以歡快的同時跑在一條 TCP 鏈接上了。
當流併發時,就會涉及到流的優先順序和依賴。優先順序高的流會被優先發送。圖片請求的優先順序要低於 CSS 和 SCRIPT,這個設計可以確保重要的東西可以被優先載入完。
直白的說就是所有的請求都是通過一個 TCP 連接併發完成。HTTP/1.x 雖然通過 pipeline 也能併發請求,但是多個請求之間的響應會被阻塞的,所以 pipeline 至今也沒有被普及應用,而 HTTP/2 做到了真正的併發請求,同時,流還支持優先順序和流量控制。
壓縮頭信息
HTTP/2 對消息頭採用 HPACK 進行壓縮傳輸,能夠節省消息頭占用的網路的流量。而 HTTP/1.x 每次請求,都會攜帶大量冗餘頭信息,浪費了很多帶寬資源。頭壓縮能夠很好的解決該問題。
二進位格式傳輸數據
HTTP/2 採用二進位格式傳輸數據。二進位格式在協議的解析和優化擴展上帶來更多的優勢和可能。
支持服務端Push消息到客戶端
當服務端需要主動推送某個資源時,便會發送一個 Frame Type 為 PUSH_PROMISE 的 Frame,裡面帶了 PUSH 需要新建的 Stream ID。意思是告訴客戶端:接下來我要用這個 ID 向你發送東西,客戶端準備好接著。客戶端解析 Frame 時,發現它是一個 PUSH_PROMISE 類型,便會準備接收服務端要推送的流。
這使得服務端能夠更快的把資源推送給客戶端。例如服務端可以主動把 JS 和 CSS 文件推送給客戶端,而不需要客戶端解析 HTML 再發送這些請求。當客戶端需要的時候,它已經在客戶端了。
此外需要註意的是,HTTP2目前在實際使用中,只用於HTTPS協議場景下,通過握手階段ClientHello與ServerHello的extension欄位協商而來,所以目前HTTP2的使用場景,都是預設安全加密的。
Nginx 啟用 HTTP/2 支持
註意事項
linux下檢查openssl version 版本,目前的版本是1.0.1e,如果http2 不生效可能是openssl版本的問題。
Nginx是在1.9.5之後支持HTTP/2的,低版本的請先升級。
新增HTTP/2模塊
由於之前安裝的Nginx沒有配置http_v2_module,所有要重新編譯一下,記住不要執行安裝操作。
切換到Nginx源碼目錄執行以下操作,pcre和zlib是博主自己的安裝目錄。
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-http_v2_module --with-pcre=/home/tools/pcre-8.00 --with-zlib=/home/tools/zlib-1.2.11
然後執行編譯
make
執行成功以後,會在源碼目錄下生成一個objs文件夾,把裡面的Nginx複製Nginx到指定安裝目錄。
cp /home/tools/nginx-1.10.3/objs/nginx /usr/local/nginx
重啟Nginx
nginx -s reload
檢查是否安裝成功,成功後配置中會存在 with-http_v2_module
nginx -V
最後你只需要在配置中增加
server {
listen 443 ssl http2;
.....省略
}
驗證網站對 HTTP/2 的支持
方法一:瀏覽網站 同時瀏覽器訪問驗證網站對 HTTP/2 的支持,如果你的網站也出現在這裡說明配置成功。
方法二:線上測試地址:https://www.ssllabs.com/ssltest/
認證級別A
方法三:谷歌瀏覽器下載HTTP/2 and SPDY indicator插件,安裝成功後,瀏覽開啟Http2的網站,右上角會顯示藍色的閃電。
疑惑
其實網站之前沒有配置HTTP/2.0的時候已經是小藍閃電了,難道是因為啟用了CDN?
在配置HTTP/2.0之後,儘管火狐瀏覽器網路請求都是HTTP/2.0,但是後臺日誌(都是動態請求),卻是HTTP/1.1?
CDN使用的是阿裡雲的服務,可能阿裡的CDN早已實現HTTP/2.0技術了。