随着基于 web 的應用和服務的增多,it 系統管理者肩上的責任也越來越重。當遇到不可預期的事件如流量達到高峰,流量增大或者内部的挑戰比如硬體的損壞或緊急維修,無論如何,你的 web 應用都必須要保持可用性。甚至現在流行的 devops 和持續傳遞(cd)也可能威脅到你的 web 服務的可靠性和性能的一緻性。

http 負載均衡是一個網絡解決方案,它将進入的 http 或 https 請求配置設定至一組提供相同的 web 應用内容的伺服器用于響應。通過将請求在這樣的多個伺服器間進行均衡,負載均衡器可以防止伺服器出現單點故障,可以提升整體的可用性和響應速度。它還可以讓你能夠簡單的通過添加或者移除伺服器來進行橫向擴充或收縮,對工作負載進行調整。
負載均衡可以提升伺服器的使用性能和最大可用性,當你的伺服器開始出現高負載時就可以使用負載均衡。或者你在為一個大型項目設計架構時,在前端使用負載均衡是一個很好的習慣。當你的環境需要擴充的時候它會很有用。
在這個教程中,我們會為 http web 伺服器配置一個基于 haproxy 的負載均衡。
<a target="_blank"></a>
對于大多數的發行版,我們可以使用發行版的包管理器來安裝 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
# yum install haproxy
本教程假設有兩台運作的 http web 伺服器,它們的 ip 位址是 192.168.100.2 和 192.168.100.3。我們将負載均衡配置在 192.168.100.4 的這台伺服器上。
為了讓 haproxy 工作正常,你需要修改 /etc/haproxy/haproxy.cfg 中的一些選項。我們會在這一節中解釋這些修改。一些配置可能因 gnu/linux 發行版的不同而變化,這些會被标注出來。
你要做的第一件事是為 haproxy 配置日志功能,在排錯時日志将很有用。日志配置可以在 /etc/haproxy/haproxy.cfg 的 global 段中找到他們。下面是針對不同的 linux 發型版的 haproxy 日志配置。
在 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 中啟用日志,将下面的内容
log /dev/log local0
log /dev/log local1 notice
然後為 haproxy 配置日志分割,編輯 /etc/rsyslog.d/ 下的 haproxy.conf (在 debian 中可能叫 49-haproxy.conf),寫入下面你的内容
下一步是設定 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 的手冊并配置它。
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 通路的那個網卡接口。
上面的設定定義了,負載均衡器的狀态統計資訊可以通過 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 的會話。
上面是我們的 web 伺服器節點的定義。伺服器有由内部名稱(如web01,web02),ip 位址和唯一的 cookie 字元串表示。cookie 字元串可以自定義,我這裡使用的是簡單的 node1,node2 ... node(n)
如果你完成了配置,現在啟動 haproxy 并驗證是否運作正常。
讓 haproxy 開機自啟,使用下面的指令
# chkconfig haproxy on
# service haproxy start
當然,防火牆需要開放 80 端口,像下面這樣
# firewallcmd permanent zone=public addport=80/tcp
# firewallcmd reload
把下面内容加至 /etc/sysconfig/iptables 中的 ":output accept" 段中
a input m state state new m tcp p tcp dport 80 j accept
重新開機iptables:
# service iptables restart
啟動 haproxy
不要忘了防火牆開放 80 端口,在 /etc/iptables.up.rules 中加入:
a input p tcp dport 80 j accept
讓 haproxy 開機自動啟動在 /etc/default/haproxy 中配置
enabled=1
啟動 haproxy:
防火牆開放 80 端口:
# ufw allow 80
檢查 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
如果我們停掉一台後端 web 服務,curl 指令仍然正常工作,請求被分發至另一台可用的 web 伺服器。
現在你有了一個完全可用的負載均衡器,以輪詢的模式對你的 web 節點進行負載均衡。還可以去實驗其他的配置選項以适應你的環境。希望這個教程可以幫助你們的 web 項目有更好的可用性。
你可能已經發現了,這個教程隻包含單台負載均衡的設定。這意味着我們仍然有單點故障的問題。在真實場景中,你應該至少部署 2 台或者 3 台負載均衡以防止意外發生,但這不是本教程的範圍。
如果你有任何問題或建議,請在評論中提出,我會盡我的努力回答。
原文釋出時間:2015-01-28
本文來自雲栖合作夥伴“linux中國”