這裡介紹如何在 Ubuntu Linux 上安裝最新版 Nginx 伺服器,讓網站支援 HTTP/2 傳輸協定,加快網頁的載入速度。
HTTP/2 是繼 1999 年 HTTP/1.1 之後所制定的新 HTTP 傳輸協定標準,其以 Google 的 SPDY 技術為基礎,具有相當優異的傳輸與處理效能,多工(Multiplexing)的新特性可以讓瀏覽器在同時間內對多個伺服器發送請求,並採用更高效率的壓縮技術,大幅縮短網頁傳輸與處理的時間。
HTTP/2 有多快?
HTTP/2 目前都是配合 HTTPS 安全加密的網頁使用,在處理效能以及資料安全性上都大幅改善,HTTP vs HTTPS Test 這個網頁工具可以讓您實際測試最新的 HTTPS 加上 HTTP/2 技術與傳統 HTTP/1.1 的效能差異,以下是我跑出來的結果。
使用傳統 HTTP/1.1 的網頁載入時間大約是 12.271 秒。
而改用 HTTPS 安全加密傳輸以及 HTTP/2 加速的結果,整個網頁的載入只花了 0.881 秒,這個差異相當驚人,以這個數據來說,若要加入網頁的載入,與其去找付費的 CDN,還不如把自己的網站升級成 HTTP/2。
升級 Nginx 版本
Nginx 網頁伺服器從 Nginx 1.9.5 版開始支援 HTTP/2,如果您的 Linux 發行版本身就已經有收錄 Nginx 1.9.5 以後的版本,就可以直接啟用 HTTP/2 的功能,但是若您的 Linux 發行版比較舊,我們就會需要先將 Nginx 升級成 1.9.5 以後的版本。
我個人網站的伺服器目前的作業系統是 Ubuntu Linux 14.04,而這個發行版所收錄的 Nginx 只有到 1.4.6 版,所以我需要自行升級 Nginx 的版本,以下是參考 Nginx 官方的文件的升級過程。
首先加入 Nginx 的 PPA:
sudo -s
add-apt-repository ppa:nginx/stable
接著升級 Nginx:
apt-get update apt-get dist-upgrade
我是直接使用 dist-upgrade
讓它自動升級,不過這樣的升級方式有很大的風險,建議事先在別台機器上測試,再讓正式的伺服器執行,另外也建議再升級之前先備份所有 Nginx 的設定檔。
在升級過程中,通常會有一些新舊設定檔的衝突問題,安裝程式會一一詢問每一個設定檔的處理方式,這部分會因為自己的設定有些差異,最常發生衝突的應該是 /etc/nginx/nginx.conf
這個檔案,我是讓安裝程式直接將舊的設定檔取代掉,基本上安裝程式不會直接把舊的設定檔刪除,而是將舊的設定檔改名為 nginx.conf.dpkg-old
,等安裝完成後,我自己再用 vimdiff
慢慢去比較與修改設定檔。
當我把 nginx.conf
處理完之後,發現網頁伺服器出了一些問題,所有的靜態網頁都正常,但是 PHP 的網頁都變成空白,後來看了 stackoverflow 網站上的討論,發現是 Nginx 網站設定檔在升級之後,PHP 的設定需要修正:
location ~ .php$ { # ... # 移除舊設定 #include fastcgi_params; # 加入新設定 include fastcgi.conf; }
舊的 Nginx 設定是引入 fastcgi_params
,而新的設定則要改成 fastcgi.conf
,其餘的設定則不用改變。
另外我發現新版的 Nginx 的服務在 logrotate 執行之後,沒有重新載入,所有的記錄還是會寫進 access.log.1
與 error.log.1
中,造成這兩個檔案過大,而 access.log
與 error.log
兩個新檔案卻是空的。這個問題可以從 /etc/logrotate.d/nginx
設定檔中修正,將 postrotate
的指令改為:
/var/log/nginx/*.log { # ... postrotate service nginx rotate >/dev/null 2>&1 endscript }
以我個人的情況而言,這樣設定完之後,Nginx 伺服器就可以正常運作了,但是因為每個網站的設定都會有差異,所以無法保證這樣的方式適用於每一個網站。
Nginx 設定 HTTP/2
在設定 Nginx 的 HTTP/2 之前,請先確認一下 Nginx 伺服器的版本,Nginx 一定要是 1.9.5 以後的版本才能使用 HTTP/2:
nginx -v
nginx version: nginx/1.10.0
只要 Nginx 的版本沒問題,要啟用 HTTP/2 就很簡單了,只要在網站的設定檔加入 http2
的設定,就可以直接使用 HTTP/2 傳輸協定了。
server { # 啟用 ssl 與 http2 listen 443 ssl http2; # 同時啟用 IPv6 的 ssl 與 http2 listen [::]:443 ssl http2; }
由於 HTTP/2 一定要與 SSL 安全加密的連線一起使用,所以在啟用 http2
的時候,也要一併啟用 ssl
,而關於 Nginx 的 HTTPS 安全加密網頁的設定與 SSL 憑證的申請,可以參考 Nginx 使用 Let’s Encrypt 免費 SSL 憑證的教學。
如果您在啟用 HTTP/2 的功能之後,網頁出現 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY
的錯誤訊息,通常是因為 ssl_ciphers
的設定有問題,只要加上適當的 ssl_ciphers
設定,應該就可以解決:
server { # ... # Mozilla 建議的 ciphersuites ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; ssl_prefer_server_ciphers on; }
這裡的 ssl_ciphers
設定是參考 Mozilla SSL Configuration Generator 的建議。
測試 HTTP/2
網站設定完成後,可以使用 KeyCDN 的 HTTP/2 測試工具來檢查一下自己的網站,看看是否有真的支援 HTTP/2。
若要在 Google Chrome 瀏覽器上檢查網站是否支援 HTTP/2,可以使用 HTTP/2 and SPDY indicator 這個外掛程式。
參考資料:Raymii.org