怎樣把網站升級到http/2

爲何要升級到http/2呢?咱們用Chrome的控制檯進行網站評測的時候,非http/2的網站會給一個建議:html

意思是說要使用http/2,我以前只是聽過http/2的一些介紹,其實http/2已經來了。http/2最大的特色是使用多路複用,對同一個域的服務器只創建一次TCP鏈接,加載多個資源,使用二進制幀傳輸,同時會對http頭部進行壓縮。使用http2會比http/1.1更加地高效,所以筆者對博客網站嘗試進行了升級。nginx

1. 升級到HTTP/2

要求nginx的最低版本是1.10.0,openssl的最低版本是1.0.2,http/2在實現上基本上只支持https。筆者的系統是centos 7,用yum安裝的nginx是1.10.2,這個版本是能夠的,可是系統的openssl是1.0.1,把系統的openssl update一下,變成1.0.2,但仍是不能夠。發現是由於nginx在編譯的時候指定的openssl是1.0.1的,因此即便升級了系統的openssl也是沒有用的,以下圖所示:git

那怎麼升級呢?nginx官方提供了兩種方法,第一種是升級操做系統,第二種是從源碼編譯新版本的nginx,咱們用第二種方法。當前nginx最新的穩定版本是1.12.1,在服務器上執行如下命令:github

wget http://nginx.org/download/nginx-1.12.1.tar.gz # 下載
tar -zxvf nginx-1.12.1.tar.gz # 解壓
cd nginx-1.12.1
./configure # 確認系統環境,生成make文件
make # 編譯
sudo make install #安裝複製代碼

configure的時候後面能夠帶參數,參數能夠用原先老版本nginx的參數,包括安裝路徑之類的,這個能夠經過執行nginx -V獲得,使得新nginx的配置和老nginx同樣。若是configure提示缺一些庫的話就相應地作些安裝,基本上就是它提示的庫後面帶上devel,如如下提示:web

./configure: error: the Google perftools module requires the Google perftoolschrome

library. You can either do not enable the module or install the library.windows

可安裝下面這個庫解決:centos

sudo yum install gperftools-devel複製代碼

新安裝後的nginx的openssl版本就對了:瀏覽器

而後添加nginx配置,本來https的listen爲:bash

listen 443 ssl;複製代碼

如今在後面加上http2:

listen 443 ssl http2;複製代碼

而後把nginx關了再開一下(由於新安裝了一個nginx,要先關一下再開),這個時候再用瀏覽器訪問,本來的http1.1:

就會變成http2:

有個細節是HTTP/2不叫2.0,這是故意的,由於1.x容易混淆,因此2的時候就不帶小版本號了,因此上面firefox的顯示實際上是不對的。

整個傳輸模型以下圖所示(圖片來自nginx):

nginx和客戶端是HTTP/2,而nginx和業務服務仍是HTTP/1.1,由於nginx的服務和業務服務一般是處於同一個內網,速度通常會很快,而nginx和客戶端的鏈接就不太可控了,若是業務服務自己支持HTTP/2,會更好。

而後咱們先看一下傳輸的流量節省了多少,以下圖所示,加載一個頁面:

能夠看到,HTTP 2在流量方面並無太大的改進,只減小了4kB(1%)的流量,下面咱們再分析緣由。HTTP 2的優點還在於它的多路複用等方面。

2. HTTP/2的優點

(1)多路複用

多路複用的意義在於能夠用同一個鏈接傳輸多個資源,進而使得之前在http 1.1所作一些優化就沒有必要了,如:

a)使用雪碧圖技術,把多張小圖合成一張大圖,減小請求數;

b)合併JS和CSS,減小請求數。

由於在http 1.1時代,因爲須要創建多個TCP鏈接,服務器須要更多的線程來處理請求,一樣地,瀏覽器也須要,因此瀏覽器會限制同一個域的同時請求數,Chrome是限制6個,總鏈接數是17個,其它瀏覽器的個數有所浮動,但差很少,讀者能夠這個網站測試本身所用的瀏覽器的限制狀況。能夠實際對比一下,http 1.1會讓資源排隊加載,以下圖所示:

但當咱們開啓了http/2以後,個數幾乎沒有限制了,以下圖所示:

你會發現這些資源都是同時加載的,後面加載的資源不須要進行排隊。也就是說理論上帶寬有多大,就能傳多快。實際的效果在筆者的博客網站上,用了一個頁面重複了5次,比較平均值,load時間只快了4%,在我這個例子並非很明顯,但並不能表明HTTP 2沒什麼用,若是nginx和業務服務的鏈接也是http/2應該會更好。

這個傳輸模型是這樣的,以下圖所示(圖片來自谷歌開發者文檔):

數據以幀(frame)的格式在同一個鏈接傳輸,而且服務還能夠提早Push一些資源給客戶端。

(2)Server Push

在上面兩張加載圖能夠看到第一個資源html沒加載以前,其它資源是不會開始加載的,由於它們是html觸發加載,如img標籤就會加載一張圖片,因此要等html下載和解析了才能加載其它資源,而http2可讓服務先把其它極可能客戶端會請求的資源先push發給你,不用等到請求的時候再發送,這樣能夠提升頁面總體的加載速度。nginx官網說目前暫不支持Server Push,但能夠下載一個http2的Node.js包寫個demo感覺一下,以下代碼:

response.push('/img/banner.png');複製代碼

(3)報文頭壓縮和二進制編碼

因爲https傳輸的數據是加密的,沒法用抓包工具觀察到這個過程,咱們能夠作些理論分析。

使用二進制傳輸的好處在於它更接近於計算機存儲特色,傳統的文本流傳輸形式存在一些解析上的複雜性,如對消息長度(Message Length)的解析要分爲5種狀況,詳見w3c,而使用二進制方式則不存在這個問題。須要注意的是http/2的二進制形式並無改變http/1.1的體系,只是把傳輸報文格式改了,以下圖所示:

上圖展現了兩個幀,一個頭部幀,還有一個數據幀。

而報文頭壓縮是這樣的,以下圖所示:

客戶端發了兩次請求,第一次請求有完整的http報文頭部,第二次請求的時候只有一個path的字段不同,可是此次報文頭它只須要發送一個path的字段就行了,這樣就大大減小了發送的量。這個的實現要求客戶端和服務同時維護一個報文頭表。上面提到的少了4kb的流量極可能是這個節省下來的。這個的意義仍是很大的,由於動態請求有時候可能只須要發送幾個字節的數據,但卻須要發送一個幾百個字節的報文頭(500 ~ 800)。


最後一個問題,HTTP/2的兼容性如何?如caniuse所示:

IE11只在windows10支持,Chrome/Safari/Firefox/Opera等瀏覽器只支持https的http/2。

若是瀏覽器不支持http/2會怎麼樣呢?也是可以正常打開的,爲何呢?由於創建https鏈接的時候須要先握手,瀏覽器或者客戶端會發送一個Client Hello的包,這個包裏面會說明它是否支持http2,以下圖所示:

nginx就可以根據握手信息決定是否使用http/2,若是客戶端不支持就使用http/1.1。這裏從一個側面知道爲何瀏覽器須要使用https和服務支持ALPN了。


參考:

  1. Introduction to HTTP/2 - 谷歌開發者文檔

  2. Why Everyone Should Be Moving To HTTP/2
  3. HTTP/2 Frequently Asked Questions

擴展:

  1. 爲何要把網站升級到HTTPS
  2. https鏈接的前幾毫秒發生了什麼
  3. WebSocket與TCP/IP
相關文章
相關標籤/搜索