使用 HAProxy 配置 HTTP 負載均衡器
隨著基于 Web 的應用和服務的增多,IT 系統管理員肩上的責任也越來越重。當遇到不可預期的事件如流量達到高峰,流量增大或者內部的挑戰比如硬件的損壞或緊急維修,無論如何,你的 Web 應用都必須要保持可用性。甚至現在流行的 devops 和持續交付(CD)也可能威脅到你的 Web 服務的可靠性和性能的一致性。
不可預測,不一致的性能表現是你無法接受的。但是我們怎樣消除這些缺點呢?大多數情況下一個合適的負載均衡解決方案可以解決這個問題。今天我會給你們介紹如何使用 HAProxy 配置 HTTP 負載均衡器。
什么是 HTTP 負載均衡?
HTTP 負載均衡是一個網絡解決方案,它將進入的 HTTP 或 HTTPs 請求分配至一組提供相同的 Web 應用內容的服務器用于響應。通過將請求在這樣的多個服務器間進行均衡,負載均衡器可以防止服務器出現單點故障,可以提升整體的可用性和響應速度。它還可以讓你能夠簡單的通過添加或者移除服務器來進行橫向擴展或收縮,對工作負載進行調整。
什么時候,什么情況下需要使用負載均衡?
負載均衡可以提升服務器的使用性能和最大可用性,當你的服務器開始出現高負載時就可以使用負載均衡。或者你在為一個大型項目設計架構時,在前端使用負載均衡是一個很好的習慣。當你的環境需要擴展的時候它會很有用。
什么是 HAProxy?
HAProxy 是一個流行的開源的 GNU/Linux 平臺下的 TCP/HTTP 服務器的負載均衡和代理軟件。HAProxy 是單線程,事件驅動架構,可以輕松的處理 10 Gbps 速率 的流量,在生產環境中被廣泛的使用。它的功能包括自動健康狀態檢查,自定義負載均衡算法,HTTPS/SSL 支持,會話速率限制等等。
這個教程要實現怎樣的負載均衡
在這個教程中,我們會為 HTTP Web 服務器配置一個基于 HAProxy 的負載均衡。
準備條件
你至少要有一臺,或者最好是兩臺 Web 服務器來驗證你的負載均衡的功能。我們假設后端的 HTTP Web 服務器已經配置好并可以運行。
在 Linux 中安裝 HAProxy
對于大多數的發行版,我們可以使用發行版的包管理器來安裝 HAProxy。
在 Debian 中安裝 HAProxy
在 Debian Wheezy 中我們需要添加源,在 /etc/apt/sources.list.d 下創建一個文件 "backports.list" ,寫入下面的內容
deb http://cdn.debian.net/debian wheezybackports main
刷新倉庫的數據,并安裝 HAProxy
# apt get update # apt get install haproxy
在 Ubuntu 中安裝 HAProxy
# apt get install haproxy
在 CentOS 和 RHEL 中安裝 HAProxy
# yum install haproxy
配置 HAProxy
本教程假設有兩臺運行的 HTTP Web 服務器,它們的 IP 地址是 192.168.100.2 和 192.168.100.3。我們將負載均衡配置在 192.168.100.4 的這臺服務器上。
為了讓 HAProxy 工作正常,你需要修改 /etc/haproxy/haproxy.cfg 中的一些選項。我們會在這一節中解釋這些修改。一些配置可能因 GNU/Linux 發行版的不同而變化,這些會被標注出來。
1. 配置日志功能
你要做的第一件事是為 HAProxy 配置日志功能,在排錯時日志將很有用。日志配置可以在 /etc/haproxy/haproxy.cfg 的 global 段中找到他們。下面是針對不同的 Linux 發型版的 HAProxy 日志配置。
CentOS 或 RHEL:
在 CentOS/RHEL中啟用日志,將下面的:
log 127.0.0.1 local2
替換為:
log 127.0.0.1 local0
然后配置 HAProxy 在 /var/log 中的日志分割,我們需要修改當前的 rsyslog 配置。為了簡潔和明了,我們在 /etc/rsyslog.d 下創建一個叫 haproxy.conf 的文件,添加下面的內容:
$ModLoad imudp $UDPServerRun 514 $template Haproxy,"%msg%\n" local0.=info /var/log/haproxy.log;Haproxy local0.notice /var/log/haproxystatus.log;Haproxy local0.* ~
這個配置會基于 $template 在 /var/log 中分割 HAProxy 日志。現在重啟 rsyslog 應用這些更改。
# service rsyslog restart
Debian 或 Ubuntu:
在 Debian 或 Ubuntu 中啟用日志,將下面的內容
log /dev/log local0 log /dev/log local1 notice
替換為:
log 127.0.0.1 local0
然后為 HAProxy 配置日志分割,編輯 /etc/rsyslog.d/ 下的 haproxy.conf (在 Debian 中可能叫 49-haproxy.conf),寫入下面你的內容
$ModLoad imudp $UDPServerRun 514 $template Haproxy,"%msg%\n" local0.=info /var/log/haproxy.log;Haproxy local0.notice /var/log/haproxystatus.log;Haproxy local0.* ~
這個配置會基于 $template 在 /var/log 中分割 HAProxy 日志。現在重啟 rsyslog 應用這些更改。
# service rsyslog restart
2. 設置默認選項
下一步是設置 HAProxy 的默認選項。在 /etc/haproxy/haproxy.cfg 的 default 段中,替換為下面的配置:
defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 20000 contimeout 5000 clitimeout 50000 srvtimeout 50000
上面的配置是當 HAProxy 為 HTTP 負載均衡時建議使用的,但是并不一定是你的環境的最優方案。你可以自己研究 HAProxy 的手冊并配置它。
3. Web 集群配置
Web 集群配置定義了一組可用的 HTTP 服務器。我們的負載均衡中的大多數設置都在這里。現在我們會創建一些基本配置,定義我們的節點。將配置文件中從 frontend 段開始的內容全部替換為下面的:
listen webfarm *:80 mode http stats enable stats uri /haproxy?stats stats realm Haproxy\ Statistics stats auth haproxy:stats balance roundrobin cookie LBN insert indirect nocache option httpclose option forwardfor server web01 192.168.100.2:80 cookie node1 check server web02 192.168.100.3:80 cookie node2 check
"listen webfarm *:80" 定義了負載均衡器監聽的地址和端口。為了教程的需要,我設置為 "*" 表示監聽在所有接口上。在真實的場景匯總,這樣設置可能不太合適,應該替換為可以從 internet 訪問的那個網卡接口。
stats enable stats uri /haproxy?stats stats realm Haproxy\ Statistics stats auth haproxy:stats
上面的設置定義了,負載均衡器的狀態統計信息可以通過 http://<load-balancer-IP>/haproxy?stats 訪問。訪問需要簡單的 HTTP 認證,用戶名為 "haproxy" 密碼為 "stats"。這些設置可以替換為你自己的認證方式。如果你不需要狀態統計信息,可以完全禁用掉。
下面是一個 HAProxy 統計信息的例子
"balance roundrobin" 這一行表明我們使用的負載均衡類型。這個教程中,我們使用簡單的輪詢算法,可以完全滿足 HTTP 負載均衡的需要。HAProxy 還提供其他的負載均衡類型:
- leastconn:將請求調度至連接數最少的服務器
- source:對請求的客戶端 IP 地址進行哈希計算,根據哈希值和服務器的權重將請求調度至后端服務器。
- uri:對 URI 的左半部分(問號之前的部分)進行哈希,根據哈希結果和服務器的權重對請求進行調度
- url_param:根據每個 HTTP GET 請求的 URL 查詢參數進行調度,使用固定的請求參數將會被調度至指定的服務器上
- hdr(name):根據 HTTP 首部中的 <name> 字段來進行調度
"cookie LBN insert indirect nocache" 這一行表示我們的負載均衡器會存儲 cookie 信息,可以將后端服務器池中的節點與某個特定會話綁定。節點的 cookie 存儲為一個自定義的名字。這里,我們使用的是 "LBN",你可以指定其他的名稱。后端節點會保存這個 cookie 的會話。
server web01 192.168.100.2:80 cookie node1 check server web02 192.168.100.3:80 cookie node2 check
上面是我們的 Web 服務器節點的定義。服務器有由內部名稱(如web01,web02),IP 地址和唯一的 cookie 字符串表示。cookie 字符串可以自定義,我這里使用的是簡單的 node1,node2 ... node(n)
啟動 HAProxy
如果你完成了配置,現在啟動 HAProxy 并驗證是否運行正常。
在 Centos/RHEL 中啟動 HAProxy
讓 HAProxy 開機自啟,使用下面的命令
# chkconfig haproxy on # service haproxy start
當然,防火墻需要開放 80 端口,像下面這樣
CentOS/RHEL 7 的防火墻
# firewallcmd permanent zone=public addport=80/tcp # firewallcmd reload
CentOS/RHEL 6 的防火墻
把下面內容加至 /etc/sysconfig/iptables 中的 ":OUTPUT ACCEPT" 段中
A INPUT m state state NEW m tcp p tcp dport 80 j ACCEPT
重啟iptables:
# service iptables restart
在 Debian 中啟動 HAProxy
啟動 HAProxy
# service haproxy start
不要忘了防火墻開放 80 端口,在 /etc/iptables.up.rules 中加入:
A INPUT p tcp dport 80 j ACCEPT
在 Ubuntu 中啟動HAProxy
讓 HAProxy 開機自動啟動在 /etc/default/haproxy 中配置
ENABLED=1
啟動 HAProxy:
# service haproxy start
防火墻開放 80 端口:
# ufw allow 80
測試 HAProxy
檢查 HAProxy 是否工作正常,我們可以這樣做
首先準備一個 test.php 文件,文件內容如下
<?php header('Content-Type: text/plain'); echo "Server IP: ".$_SERVER['SERVER_ADDR']; echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR']; ?>
這個 PHP 文件會告訴我們哪臺服務器(如負載均衡)轉發了請求,哪臺后端 Web 服務器實際處理了請求。
將這個 PHP 文件放到兩個后端 Web 服務器的 Web 根目錄中。然后用 curl 命令通過負載均衡器(192.168.100.4)訪問這個文件
$ curl http://192.168.100.4/test.php
我們多次運行這個命令此時,會發現交替的輸出下面的內容(因為使用了輪詢算法):
Server IP: 192.168.100.2 X-Forwarded-for: 192.168.100.4
Server IP: 192.168.100.3 X-Forwarded-for: 192.168.100.4
如果我們停掉一臺后端 Web 服務,curl 命令仍然正常工作,請求被分發至另一臺可用的 Web 服務器。
總結
現在你有了一個完全可用的負載均衡器,以輪詢的模式對你的 Web 節點進行負載均衡。還可以去實驗其他的配置選項以適應你的環境。希望這個教程可以幫助你們的 Web 項目有更好的可用性。
你可能已經發現了,這個教程只包含單臺負載均衡的設置。這意味著我們仍然有單點故障的問題。在真實場景中,你應該至少部署 2 臺或者 3 臺負載均衡以防止意外發生,但這不是本教程的范圍。
如果你有任何問題或建議,請在評論中提出,我會盡我的努力回答。
via: http://xmodulo.com/haproxy-http-load-balancer-linux.html
作者:Jaroslav ?těpánek 譯者:Liao 校對:wxy