HAProxy、Nginx 配置 HTTP/2 完整指南
基於最近對HTTP/2的爭論和它的優勢,是時候升級底層架構了。這篇文章將會介紹如何在安裝和配置HAProxy和Ngnix(使用ssl終端)。為了簡化流程,我建議你准備好使用Docker鏡像。
如果你想跳過安裝環節或你只對配置環節感興趣,可以跳至配置部分。
我為什么需要關注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/haproxy和million12/nginx 這兩個鏡像。里面的配置是我們討論后的最終結果。
你可以運行整個棧通過使用docker-compose.yml文件。注意我們是通過haproxy容器里的web.server主機名連接Nignx的,那個域名就是當前haproxy.cfg使用的主機名。
連接https://haproxy:8443你就會看到屏幕顯示出如下內容(注意藍色的HTTP/2提示部分)。
http://m12.io/blog/http-2-with-haproxy-and-nginx-guide
https://github.com/million12/docker-haproxy
https://github.com/million12/docker-nginx