HAProxy、Nginx 配置 HTTP/2 完整指南

oschina發表於2016-03-31

基於最近對HTTP/2的爭論和它的優勢,是時候升級底層架構了。這篇文章將會介紹如何在安裝和配置HAProxy和Ngnix(使用ssl終端)。為了簡化流程,我建議你準備好使用Docker映象。

HAProxy、Nginx 配置 HTTP/2 完整指南

如果你想跳過安裝環節或你只對配置環節感興趣,可以跳至配置部分。

我為什麼需要關注HTTP/2?

這裡有一些介紹HTTP/2益處的文章-而且我鼓勵你去讀一讀。下面我將重點介紹我認為比較重要的幾點。

HTTP/2的主要優勢:

  • 使用二進位制資料(不像HTTP/1.1一樣使用明文)而且它使用了header資料壓縮。不用再為header和cookie的大小而擔心了。
  • 它是完全多元化的,為了提升併發性可以使用一個連線載入多種資源。你的網站效能在需要引入多種資源的時候會表現得更好,因為現在它們可以在一次TCP連線中全部載入,在非阻塞模式中。域名切分和資源級聯變成了反面模式。簡單來說:你的網站載入會更快。
  • 它允許伺服器提前推送請求到客戶端的快取(目前Ngnix不支援這個特性)
  • 它使用新的ALPN擴充套件,那將允許更快地加密連線。這個加密協議在初始化連線的階段是可用的。

今天我可以使用它嗎?

是的,你可以。正如你所看到的在Can I Use上的服務那樣,所有現代瀏覽器現在都支援HTTP/2,這裡包括IE11和Edge。唯一的例外是移動端的Opera Mini和Android瀏覽器不支援它。

此外,下面描述的配置都會確保客戶端在不支援HTTP/2的情況下,退回到HTTP/1.1。這非常重要:你的網站應該為那些老版本瀏覽器或搜尋引擎爬蟲提供訪問支援。

安裝

我會在CentOS 7下安裝,如果你使用其他Linux釋出版本,你可以簡單調整下程式碼。

你需要做的:

1.站點能跑通SSL。如果你還沒有虛擬證書的話,你需要使用虛擬證書(簡單)。

2.Ngnix 1.9.5 或更新版本( 簡單 )。

3. 安裝配置好OpenSSL的HAPorxy 1.6或更新版( 需要一些技巧 )。

4.良好的HAPRoxy和Ngnix配置( 簡單 )。

5.確認你是否已經在使用HTTP/2,HTTP/2 and SPDY indicator 對Chrome友好。

OpenSSL部分是需要一些技巧,因為大部分有OpwnSSL 1.0.1(或者更舊的版本)的Linux分支都不支援ALPN(應用層協議協商)。ALPN協議允許應用層去協商,這個協議將被用在連線中,而且這是基本的,如果我們要在相同的TCP埠支援HTTP/2和HTTP/1。除此之外,HTTP/2在HAProxy中只支援使用ALPN,所以它一定會在我們的列表裡。

如果你對安裝流程熟悉的話,請直接跳至配置部分.

1.獲取 SSL 證書

你可以很便宜的從ssl2buy.com上買到信任證書,那裡有許多靠譜發行機構的代售。我曾經在那裡買了一堆證書而且我推薦他們的服務和客戶支援。你可以從那裡拿到低於20美元的AphaSSL證書。

如果你需要為HAProxy或Nginx生成虛擬證書,你可以使用下面的命令:

我們需要在下一步的配置中使用生成的證書和祕鑰。

2.Nginx 安裝

在CentOS 7上安裝Ngnix 1.9十分簡單。唯一需要做的就是使用主線版YUM源,而不是穩定版。就像Ngnix.org.oage上描述的那樣,把yum源的配置放到/etc/yum.repos.d/nginx.repo位置然後執行yum install:

搞定。

讓我們建立一個Ngnix vhost.conf(虛擬主機配置檔案)確保我們的Nginx在擁有HTTP/2的情況下正常工作。下面是一個簡單的vhost配置:

第一點:關鍵點是在listen 443 default_server ssl http2那一行。這就相當於你使用了HTTP/2。

第二點:現在忽略第三行listen 81部分的配置 – 我們一會再回來看這部分。

第三點:我使用使用標準的80/443埠在Docker映象裡跑這個樣例,所以它們不會和我的host主機上的任何埠發生衝突。如果有需要,你可以把它調整至適用你的需要。

第四點:使用在獲取SSL證書那一步生成的dummy.crt和dummy.key。

好了,當你使用https://協議連線站點時,HTTP/2提示器會提示你站點正在執行HTTP/2協議。

恭喜你,你的Ngnix已經在執行HTTP/2了!

3. OpenSSL 和 HAProxy 安裝

這一部分有點棘手。我們需要編譯OpenSSL 1.0.2的原始碼(因為在yum中還沒有可用的資源)並且在之後的HAProxy重編譯中還會使用到它。

建立OpenSSL的工作,我們使用no-shared引數,並且HAProxy是通過靜態方式連線到OpenSSL的。我遵照的是HAProxy官方的README。但可笑的是,我最終還是採用了其他的方式……並且要非常足智多謀。你會常常去讀這些冗長且乏味的README檔案嗎?

在那之後,你應該已經編譯通過HAProxy且安裝好了。測試一下:

haproxy -vv

4.配置

這是一個我們將用到完整的/etc/haproxy/haproxy.cfg(HAProxy配置):

最本質的部分在這:

這裡我們定義了HTTPS前端介面在客戶端請求HAProxy時監聽443埠。

請求被後端的nodes-http2還是nodes-http處理取決於客戶端是否支援HTTP2.注意我們決定SSL在HAProxy上使用這個配置,連線對後端伺服器來說是被解密過的。我們的後端伺服器可以被HAProxy用web伺服器的域名訪問(這就是執行過程中的Nginx,就像我們上面說的)。

在bind *:443 line with alpn h2,http/1.1一行我們建議為了方便客戶端使用最好兩種協議(HTTP/2 and HTTP/1.1)都支援。

這樣的話瀏覽器即使不支援HTTP/2,也可以瀏覽我們的網站。

use_backend nodes-http2 if { ssl_fc_alpn -i h2 } 支援HTTP/2的客戶端會被重定向到nodes-http2後端節點,剩下使用HTTP/1.1協議的將被nodes-http處理。如果你想讓後端相容還不支援HTTP/2的客戶端,這件事十分重要的。

因此我們會有下面這一行:

server node1 web.server:81 check send-proxy

在這裡,我們只討論了HAProxy和HTTP/2協議。通常它連線web.server在81埠。我們還有更令人高興的驚喜嗎?

讓我們用nginx下列虛擬主機配置(如上所述):

這一行:listen 81 default_server http2 proxy_protocol;

定義了伺服器在埠81,會處理HTTP/2的請求。請注意,我們無法在伺服器使用443埠進行SSL連線:SSL連線已經被HAProxy解密過了,所以現在我們有一個非加密連線。因此我們需要限制伺服器的81埠只使用HTTP/2,不使用SSL。

題外話:小也有proxy_protocol關鍵詞。在haproxy.cfg等效傳送代理,在後端伺服器配置。代理協議是獨立出來的,這兒有篇文章很好的解釋了原因。簡而言之,它允許通過HAProxy後端伺服器傳送客戶端的IP地址和埠號,這通常是非常理想的。

你可以使用上面的配置執行HAProxy:

HAProxy F / etc / HAProxy / haproxy.cfg

現在你應該能夠連線到您的代理主機(例如https://localhost:443/),看到它正在執行HTTP / 2。如果你在Firefox的測試,檢查網路請求頭的標題,你會看到X-Firefox-Spdy: “h2″。

Docker images

如果你早已經會使用Docker,你可以用我們的MILLION12映象。當Docker還是1.0版本的時候我們已經開始使用Docker很長時間了(MILLION12這是我們的倉庫地址),而且我們已經構建了一堆有用的映象 。在這個例子裡,我們將使用million12/haproxymillion12/nginx 這兩個映象。裡面的配置是我們討論後的最終結果。

你可以執行整個棧通過使用docker-compose.yml檔案。注意我們是通過haproxy容器裡的web.server主機名連線Nignx的,那個域名就是當前haproxy.cfg使用的主機名。

連線https://haproxy:8443你就會看到螢幕顯示出如下內容(注意藍色的HTTP/2提示部分)。

HAProxy、Nginx 配置 HTTP/2 完整指南

HAProxy、Nginx 配置 HTTP/2 完整指南

如果你想看看使用這些Docker映象和上述配置的真實的產品工程,開啟https://PrototypeBrewery.io。Prototype Brewery是我們的產品,一個計劃和構建互動式web專案的原型工具。開啟看看吧,我們已經在使用HTTP/2了(別忘了註冊)。

總結

正如你看到的,遷移到HTTP/2真的很簡單,你今天就能做掉。 沒有什麼理由讓你再等下去了,主流瀏覽器都已經支援它了。而且即使回遷到HTTP/1.1上你仍然是安全的。

如果你認為我在這裡漏寫了什麼,或者還有什麼可以改進的,請在下面留言評論。

相關文章