HAProxy是什么
HAProxy是一個免費的負載均衡軟件,可以運行於大部分主流的Linux操作系統上。
HAProxy提供了L4(TCP)和L7(HTTP)兩種負載均衡能力,具備豐富的功能。HAProxy的社區非常活躍,版本更新快速(最新穩定版1.7.2於2017/01/13推出)。最關鍵的是,HAProxy具備媲美商用負載均衡器的性能和穩定性。
因為HAProxy的上述優點,它當前不僅僅是免費負載均衡軟件的首選,更幾乎成為了唯一選擇。
HAProxy的核心能力和關鍵特性
HAProxy的核心功能
- 負載均衡:L4和L7兩種模式,支持RR/靜態RR/LC/IP Hash/URI Hash/URL_PARAM Hash/HTTP_HEADER Hash等豐富的負載均衡算法
- 健康檢查:支持TCP和HTTP兩種健康檢查模式
- 會話保持:對於未實現會話共享的應用集群,可通過Insert Cookie/Rewrite Cookie/Prefix Cookie,以及上述的多種Hash方式實現會話保持
- SSL:HAProxy可以解析HTTPS協議,並能夠將請求解密為HTTP后向后端傳輸
- HTTP請求重寫與重定向
- 監控與統計:HAProxy提供了基於Web的統計信息頁面,展現健康狀態和流量數據。基於此功能,使用者可以開發監控程序來監控HAProxy的狀態
HAProxy的關鍵特性
性能
- 采用單線程、事件驅動、非阻塞模型,減少上下文切換的消耗,能在1ms內處理數百個請求。並且每個會話只占用數KB的內存。
- 大量精細的性能優化,如O(1)復雜度的事件檢查器、延遲更新技術、Single-buffereing、Zero-copy forwarding等等,這些技術使得HAProxy在中等負載下只占用極低的CPU資源。
- HAProxy大量利用操作系統本身的功能特性,使得其在處理請求時能發揮極高的性能,通常情況下,HAProxy自身只占用15%的處理時間,剩余的85%都是在系統內核層完成的。
- HAProxy作者在8年前(2009)年使用1.4版本進行了一次測試,單個HAProxy進程的處理能力突破了10萬請求/秒,並輕松占滿了10Gbps的網絡帶寬。
穩定性
作為建議以單進程模式運行的程序,HAProxy對穩定性的要求是十分嚴苛的。按照作者的說法,HAProxy在13年間從未出現過一個會導致其崩潰的BUG,HAProxy一旦成功啟動,除非操作系統或硬件故障,否則就不會崩潰(我覺得可能多少還是有誇大的成分)。
在上文中提到過,HAProxy的大部分工作都是在操作系統內核完成的,所以HAProxy的穩定性主要依賴於操作系統,作者建議使用2.6或3.x的Linux內核,對sysctls參數進行精細的優化,並且確保主機有足夠的內存。這樣HAProxy就能夠持續滿負載穩定運行數年之久。
個人的建議:
- 使用3.x內核的Linux操作系統運行HAProxy
- 運行HAProxy的主機上不要部署其他的應用,確保HAProxy獨占資源,同時避免其他應用引發操作系統或主機的故障
- 至少為HAProxy配備一台備機,以應對主機硬件故障、斷電等突發情況(搭建雙活HAProxy的方法在后文中有描述)
- sysctl的建議配置(並不是萬用配置,仍然需要針對具體情況進行更精細的調整,但可以作為首次使用HAProxy的初始配置使用):
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65023
net.ipv4.tcp_max_syn_backlog = 10240
net.ipv4.tcp_max_tw_buckets = 400000
net.ipv4.tcp_max_orphans = 60000
net.ipv4.tcp_synack_retries = 3
net.core.somaxconn = 10000
HAProxy的安裝和運行
下面介紹在CentOS7中安裝和運行HAProxy最新穩定版(1.7.2)的方法
安裝
-
為HAProxy創建用戶和用戶組,此例中用戶和用戶組都是”ha”。注意,如果想要讓HAProxy監聽1024以下的端口,則需要以root用戶來啟動
-
下載並解壓
1 wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.2.tar.gz
2 tar -xzf haproxy-1.7.2.tar.gz
- 編譯並安裝
1 make PREFIX=/home/ha/haproxy TARGET=linux2628
2 make install PREFIX=/home/ha/haproxy
PREFIX為指定的安裝路徑,TARGET則根據當前操作系統內核版本指定:
1 - linux22 for Linux 2.2
2 - linux24 for Linux 2.4 and above (default)
3 - linux24e for Linux 2.4 with support for a working epoll (> 0.21)
4 - linux26 for Linux 2.6 and above
5 - linux2628 for Linux 2.6.28, 3.x, and above (enables splice and tproxy)
此例中,我們的操作系統內核版本為3.10.0,所以TARGET指定為linux2628
- 創建HAProxy配置文件
1 mkdir -p /home/ha/haproxy/conf
2 vi /home/ha/haproxy/conf/haproxy.cfg
我們先創建一個最簡單配置文件:
global #全局屬性
daemon #以daemon方式在后台運行
maxconn 256 #最大同時256連接
pidfile /home/ha/haproxy/conf/haproxy.pid #指定保存HAProxy進程號的文件
defaults #默認參數
mode http #http模式
timeout connect 5000ms #連接server端超時5s
timeout client 50000ms #客戶端響應超時50s
timeout server 50000ms #server端響應超時50s
frontend http-in #前端服務http-in
bind *:8080 #監聽8080端口
default_backend servers #請求轉發至名為"servers"的后端服務
backend servers #后端服務servers
server server1 127.0.0.1:8000 maxconn 32 #backend servers中只有一個后端服務,名字叫server1,起在本機的8000端口,HAProxy同時最多向這個服務發起32個連接
更加詳細的配置會在后面章節中進行說明
注意:HAProxy要求系統的ulimit -n參數大於[maxconn*2+18],在設置較大的maxconn時,注意檢查並修改ulimit -n參數
- 將HAProxy注冊為系統服務
在/etc/init.d目錄下添加HAProxy服務的啟停腳本:
vi /etc/init.d/haproxy
#! /bin/sh
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/ha/haproxy/sbin
PROGDIR=/home/ha/haproxy
PROGNAME=haproxy
DAEMON=$PROGDIR/sbin/$PROGNAME
CONFIG=$PROGDIR/conf/$PROGNAME.cfg
PIDFILE=$PROGDIR/conf/$PROGNAME.pid
DESC="HAProxy daemon"
SCRIPTNAME=/etc/init.d/$PROGNAME
# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
start()
{
echo -e "Starting $DESC: $PROGNAME\n"
$DAEMON -f $CONFIG
echo "."
}
stop()
{
echo -e "Stopping $DESC: $PROGNAME\n"
haproxy_pid="$(cat $PIDFILE)"
kill $haproxy_pid
echo "."
}
restart()
{
echo -e "Restarting $DESC: $PROGNAME\n"
$DAEMON -f $CONFIG -p $PIDFILE -sf $(cat $PIDFILE)
echo "."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
exit 1
;;
esac
exit 0
運行
啟動、停止和重啟:
service haproxy start
service haproxy stop
service haproxy restart
添加日志
HAProxy不會直接輸出文件日志,所以我們要借助Linux的rsyslog來讓HAProxy輸出日志
- 修改haproxy.cfg
在global域和defaults域中添加:
global
...
log 127.0.0.1 local0 info
log 127.0.0.1 local1 warning
...
defaults
...
log global
...
意思是將info級(及以上)的日志推送到rsyslog的local0接口,將warn級(及以上)的日志推送到rsyslog的local1接口,並且所有frontend都默認使用global中的日志配置。
注:info級的日志會打印HAProxy處理的每一條請求,會占用很大的磁盤空間,在生產環境中,建議將日志級別調整為notice
- 為rsyslog添加haproxy日志的配置
vi /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
$FileCreateMode 0644 #日志文件的權限
$FileOwner ha #日志文件的owner
local0.* /var/log/haproxy.log #local0接口對應的日志輸出文件
local1.* /var/log/haproxy_warn.log #local1接口對應的日志輸出文件
- 修改rsyslog的啟動參數
vi /etc/sysconfig/rsyslog
# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3.
# If you want to use them, switch to compatibility mode 2 by "-c 2"
# See rsyslogd(8) for more details
SYSLOGD_OPTIONS="-c 2 -r -m 0"
- 重啟rsyslog和HAProxy
service rsyslog restart
service haproxy restart
此時就應該能在/var/log目錄下看到haproxy的日志文件了
- 用logrotate進行日志切分
通過rsyslog輸出的日志是不會進行切分的,所以需要依靠Linux提供的logrotate來進行切分工作
使用root用戶,創建haproxy日志切分配置文件:
mkdir /root/logrotate
vi /root/logrotate/haproxy
/var/log/haproxy.log /var/log/haproxy_warn.log { #切分的兩個文件名
daily #按天切分
rotate 7 #保留7份
create 0644 ha ha #創建新文件的權限、用戶、用戶組
compress #壓縮舊日志
delaycompress #延遲一天壓縮
missingok #忽略文件不存在的錯誤
dateext #舊日志加上日志后綴
sharedscripts #切分后的重啟腳本只運行一次
postrotate #切分后運行腳本重載rsyslog,讓rsyslog向新的日志文件中輸出日志
/bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) &>/dev/null
endscript
}
並配置在crontab中運行:
0 0 * * * /usr/sbin/logrotate /root/logrotate/haproxy
使用HAProxy搭建L7負載均衡器
總體方案
本節中,我們將使用HAProxy搭建一個L7負載均衡器,應用如下功能
- 負載均衡
- 會話保持
- 健康檢查
- 根據URI前綴向不同的后端集群轉發
- 監控頁面
架構如下:
架構中共有6個后端服務,划分為3組,每組中2個服務:
- ms1:服務URI前綴為ms1/的請求
- ms2:服務URI前綴為ms2/的請求
- def:服務其他請求
搭建
- 搭建后端服務
部署6個后端服務,可以使用任意的Web服務,如Nginx、Apache HTTPD、Tomcat、Jetty等,具體Web服務的安裝過程省略。
此例中,我們在192.168.8.111和192.168.8.112兩台主機上分別安裝了3個Nginx:
ms1.srv1 - 192.168.8.111:8080
ms1.srv2 - 192.168.8.112:8080
ms2.srv1 - 192.168.8.111:8081
ms2.srv2 - 192.168.8.112:8081
def.srv1 - 192.168.8.111:8082
def.srv1 - 192.168.8.111:8082
在這6個Nginx服務分別部署健康檢查頁面healthCheck.html,頁面內容任意。確保通過http://ip:port/healthCheck.html可以訪問到這個頁面
接下來在6個Nginx服務中部署服務頁面:
在第一組中部署ms1/demo.html
在第二組中部署ms2/demo.html
在第三組中部署def/demo.html
demo.html的內容,以部署在192.168.8.111:8080上的為例:
Hello! This is ms1.srv1!
部署在192.168.8.112:8080上的就應該是
Hello! This is ms1.srv2!
以此類推
- 搭建HAProxy
在192.168.8.110主機安裝HAProxy
HAProxy的安裝和配置步驟如上一章中描述,此處略去
HAProxy配置文件:
global
daemon
maxconn 30000 #ulimit -n至少為60018
user ha
pidfile /home/ha/haproxy/conf/haproxy.pid
log 127.0.0.1 local0 info
log 127.0.0.1 local1 warning
defaults
mode http
log global
option http-keep-alive #使用keepAlive連接
option forwardfor #記錄客戶端IP在X-Forwarded-For頭域中
option httplog #開啟httplog,HAProxy會記錄更豐富的請求信息
timeout connect 5000ms
timeout client 10000ms
timeout server 50000ms
timeout http-request 20000ms #連接創建從客戶端讀取完整HTTP請求的超時時間,用於避免類DDOS攻擊
option httpchk GET /healthCheck.html #定義默認的健康檢查策略
frontend http-in
bind *:9001
maxconn 30000 #定義此端口上的maxconn
acl url_ms1 path_beg -i /ms1/ #定義ACL,當uri以/ms1/開頭時,ACL[url_ms1]為true
acl url_ms2 path_beg -i /ms2/ #同上,url_ms2
use_backend ms1 if url_ms1 #當[url_ms1]為true時,定向到后端服務群ms1中
use_backend ms2 if url_ms2 #當[url_ms2]為true時,定向到后端服務群ms2中
default_backend default_servers #其他情況時,定向到后端服務群default_servers中
backend ms1 #定義后端服務群ms1
balance roundrobin #使用RR負載均衡算法
cookie HA_STICKY_ms1 insert indirect nocache #會話保持策略,insert名為"HA_STICKY_ms1"的cookie
#定義后端server[ms1.srv1],請求定向到該server時會在響應中寫入cookie值[ms1.srv1]
#針對此server的maxconn設置為300
#應用默認健康檢查策略,健康檢查間隔和超時時間為2000ms,兩次成功視為節點UP,三次失敗視為節點DOWN
server ms1.srv1 192.168.8.111:8080 cookie ms1.srv1 maxconn 300 check inter 2000ms rise 2 fall 3
#同上,inter 2000ms rise 2 fall 3是默認值,可以省略
server ms1.srv2 192.168.8.112:8080 cookie ms1.srv2 maxconn 300 check
backend ms2 #定義后端服務群ms2
balance roundrobin
cookie HA_STICKY_ms2 insert indirect nocache
server ms2.srv1 192.168.8.111:8081 cookie ms2.srv1 maxconn 300 check
server ms2.srv2 192.168.8.112:8081 cookie ms2.srv2 maxconn 300 check
backend default_servers #定義后端服務群default_servers
balance roundrobin
cookie HA_STICKY_def insert indirect nocache
server def.srv1 192.168.8.111:8082 cookie def.srv1 maxconn 300 check
server def.srv2 192.168.8.112:8082 cookie def.srv2 maxconn 300 check
listen stats #定義監控頁面
bind *:1080 #綁定端口1080
stats refresh 30s #每30秒更新監控數據
stats uri /stats #訪問監控頁面的uri
stats realm HAProxy\ Stats #監控頁面的認證提示
stats auth admin:admin #監控頁面的用戶名和密碼
修改完成后,啟動HAProxy
1 service haproxy start
測試
首先,訪問一下監控頁面http://192.168.8.110:1080/stats 並按提示輸入用戶名密碼
接下來就能看到監控頁面:
監控頁面中列出了我們配置的所有frontend和backend服務,以及它們的詳細指標。如連接數,隊列情況,session rate,流量,后端服務的健康狀態等等
接下來,我們一一測試在HAProxy中配置的功能
- 健康檢查
從監控頁面中就可以直接看出健康檢查配置的是否正確,上圖中可以看到,backend ms1、ms2、default_servers下屬的6個后端服務的Status都是20h28m UP,代表健康狀態已持續了20小時28分鍾,而LastChk顯示L7OK/200 in 1ms則代表在1ms前進行了L7的健康檢查(即HTTP請求方式的健康檢查),返回碼為200
此時我們將ms1.srv1中的healthCheck.html改名
mv healthCheck.html healthCheck.html.bak
然后再去看監控頁面:
ms1.srv1的狀態變成了2s DOWN,LastChk則是L7STS/404 in 2ms,代表上次健康檢查返回了404
再恢復healthCheck.html,很快就能看到ms1.srv1重新恢復到UP狀態。
- 通過URI前綴轉發請求
訪問http://192.168.8.110:9001/ms1/demo.html :
可以看到成功定向到了ms1.srv1上
訪問http://192.168.8.110:9001/ms2/demo.html :
訪問http://192.168.8.110:9001/def/demo.html :
3) 負載均衡和會話保持策略
在分別訪問過ms1/demo.html, ms2/demo.html, m3/demo.html后,查看一下瀏覽器的Cookie:
可以看到HAProxy已經回寫了三個用於會話保持的cookie,此時反復刷新這三個頁面,會發現總是被定向到*.srv1上
接下來我們刪除HA_STICKY_ms1這條cookie,然后再訪問ms1/demo.html,會看到:
同時也被新寫入了一條Cookie:
如果發現仍然被定位到ms1.srv1,同時也沒有寫入新的HA_STICKY_ms1 Cookie,那么可能是瀏覽器緩存了ms1/demo.html頁面,請求並沒有到達HAProxy。F5刷新一下應該就可以了。
使用HAProxy搭建L4負載均衡器
HAProxy作為L4負載均衡器工作時,不會去解析任何與HTTP協議相關的內容,只在傳輸層對數據包進行處理。也就是說,以L4模式運行的HAProxy,無法實現根據URL向不同后端轉發、通過cookie實現會話保持等功能。
同時,在L4模式下工作的HAProxy也無法提供監控頁面。
但作為L4負載均衡器的HAProxy能夠提供更高的性能,適合於基於套接字的服務(如數據庫、消息隊列、RPC、郵件服務、Redis等),或不需要邏輯規則判斷,並已實現了會話共享的HTTP服務。
總體方案
本例中,我們使用HAProxy以L4方式來代理兩個HTTP服務,不提供會話保持。
global
daemon
maxconn 30000 #ulimit -n至少為60018
user ha
pidfile /home/ha/haproxy/conf/haproxy.pid
log 127.0.0.1 local0 info
log 127.0.0.1 local1 warning
defaults
mode tcp
log global
option tcplog #開啟tcplog
timeout connect 5000ms
timeout client 10000ms
timeout server 10000ms #TCP模式下,應將timeout client和timeout server設置為一樣的,以防止出現問題
option httpchk GET /healthCheck.html #定義默認的健康檢查策略
frontend http-in
bind *:9002
maxconn 30000 #定義此端口上的maxconn
default_backend default_servers #請求定向至后端服務群default_servers
backend default_servers #定義后端服務群default_servers
balance roundrobin
server def.srv1 192.168.8.111:8082 maxconn 300 check
server def.srv2 192.168.8.112:8082 maxconn 300 check
L4模式下的會話保持
雖然TCP模式下的HAProxy無法通過HTTP Cookie實現會話保持,但可以很方便的實現基於客戶端IP的會話保持。只需將
balance roundrobin
改為
balance source
此外,HAProxy提供了強大的stick-table功能,HAProxy可以從傳輸層的數據包中采樣出大量的屬性,並將這些屬性作為會話保持的策略寫入stick-table中。
本文中不對stick-table進行深入探討,如需要了解,可參考官方文檔configuration.html#4-stick-table
HAProxy關鍵配置詳解
總覽
HAProxy的配置文件共有5個域
- global:用於配置全局參數
- default:用於配置所有frontend和backend的默認屬性
- frontend:用於配置前端服務(即HAProxy自身提供的服務)實例
- backend:用於配置后端服務(即HAProxy后面接的服務)實例組
- listen:frontend+backend的組合配置,可以理解成更簡潔的配置方法
global域的關鍵配置
- daemon:指定HAProxy以后台模式運行,通常情況下都應該使用這一配置
- user [username] :指定HAProxy進程所屬的用戶
- group [groupname] :指定HAProxy進程所屬的用戶組
- log [address] [device] [maxlevel] [minlevel]:日志輸出配置,如log 127.0.0.1 local0 info warning,即向本機rsyslog或syslog的local0輸出info到warning級別的日志。其中[minlevel]可以省略。HAProxy的日志共有8個級別,從高到低為emerg/alert/crit/err/warning/notice/info/debug
- pidfile :指定記錄HAProxy進程號的文件絕對路徑。主要用於HAProxy進程的停止和重啟動作。
- maxconn :HAProxy進程同時處理的連接數,當連接數達到這一數值時,HAProxy將停止接收連接請求
frontend域的關鍵配置
- acl [name] [criterion] [flags] [operator] [value]:定義一條ACL,ACL是根據數據包的指定屬性以指定表達式計算出的true/false值。如”acl url_ms1 path_beg -i /ms1/”定義了名為url_ms1的ACL,該ACL在請求uri以/ms1/開頭(忽略大小寫)時為true
- bind [ip]:[port]:frontend服務監聽的端口
- default_backend [name]:frontend對應的默認backend
- disabled:禁用此frontend
- http-request [operation] [condition]:對所有到達此frontend的HTTP請求應用的策略,例如可以拒絕、要求認證、添加header、替換header、定義ACL等等。
- http-response [operation] [condition]:對所有從此frontend返回的HTTP響應應用的策略,大體同上
- log:同global域的log配置,僅應用於此frontend。如果要沿用global域的log配置,則此處配置為log global
- maxconn:同global域的maxconn,僅應用於此frontend
- mode:此frontend的工作模式,主要有http和tcp兩種,對應L7和L4兩種負載均衡模式
- option forwardfor:在請求中添加X-Forwarded-For Header,記錄客戶端ip
- option http-keep-alive:以KeepAlive模式提供服務
- option httpclose:與http-keep-alive對應,關閉KeepAlive模式,如果HAProxy主要提供的是啥接口類型的服務,可以考慮采用httpclose模式,以節省連接數資源。但如果這樣做了,接口的調用端將不能使用HTTP連接池
- option httplog:開啟httplog,HAProxy將會以類似Apache HTTP或Nginx的格式來記錄請求日志
- option tcplog:開啟tcplog,HAProxy將會在日志中記錄數據包在傳輸層的更多屬性
- stats uri [uri]:在此frontend上開啟監控頁面,通過[uri]訪問
- stats refresh [time]:監控數據刷新周期
- stats auth [user]:[password]:監控頁面的認證用戶名密碼
- timeout client [time]:指連接創建后,客戶端持續不發送數據的超時時間
- timeout http-request [time]:指連接創建后,客戶端沒能發送完整HTTP請求的超時時間,主要用於防止DoS類攻擊,即創建連接后,以非常緩慢的速度發送請求包,導致HAProxy連接被長時間占用
- use_backend [backend] if|unless [acl]:與ACL搭配使用,在滿足/不滿足ACL時轉發至指定的backend
backend域的關鍵配置
-
acl:同frontend域
-
balance [algorithm]:在此backend下所有server間的負載均衡算法,常用的有roundrobin和source,完整的算法說明見官方文檔configuration.html#4.2-balance
-
cookie:在backend server間啟用基於cookie的會話保持策略,最常用的是insert方式,如cookie HA_STICKY_ms1 insert indirect nocache,指HAProxy將在響應中插入名為HA_STICKY_ms1的cookie,其值為對應的server定義中指定的值,並根據請求中此cookie的值決定轉發至哪個server。indirect代表如果請求中已經帶有合法的HA_STICK_ms1 cookie,則HAProxy不會在響應中再次插入此cookie,nocache則代表禁止鏈路上的所有網關和緩存服務器緩存帶有Set-Cookie頭的響應。
-
default-server:用於指定此backend下所有server的默認設置。具體見下面的server配置。
-
disabled:禁用此backend
-
http-request/http-response:同frontend域
-
log:同frontend域
-
mode:同frontend域
-
option forwardfor:同frontend域
-
option http-keep-alive:同frontend域
-
option httpclose:同frontend域
-
option httpchk [METHOD] [URL] [VERSION]:定義以http方式進行的健康檢查策略。如option httpchk GET /healthCheck.html HTTP/1.1
-
option httplog:同frontend域
-
option tcplog:同frontend域
-
server [name] [ip]:[port] [params]:定義backend中的一個后端server,[params]用於指定這個server的參數,常用的包括有:
check:指定此參數時,HAProxy將會對此server執行健康檢查,檢查方法在option httpchk中配置。同時還可以在check后指定inter, rise, fall三個參數,分別代表健康檢查的周期、連續幾次成功認為server UP,連續幾次失敗認為server DOWN,默認值是inter 2000ms rise 2 fall 3
cookie [value]:用於配合基於cookie的會話保持,如cookie ms1.srv1代表交由此server處理的請求會在響應中寫入值為ms1.srv1的cookie(具體的cookie名則在backend域中的cookie設置中指定)
maxconn:指HAProxy最多同時向此server發起的連接數,當連接數到達maxconn后,向此server發起的新連接會進入等待隊列。默認為0,即無限
maxqueue:等待隊列的長度,當隊列已滿后,后續請求將會發至此backend下的其他server,默認為0,即無限
weight:server的權重,0-256,權重越大,分給這個server的請求就越多。weight為0的server將不會被分配任何新的連接。所有server默認weight為1 -
timeout connect [time]:指HAProxy嘗試與backend server創建連接的超時時間
-
timeout check [time]:默認情況下,健康檢查的連接+響應超時時間為server命令中指定的inter值,如果配置了timeout check,HAProxy會以inter作為健康檢查請求的連接超時時間,並以timeout check的值作為健康檢查請求的響應超時時間
-
timeout server [time]:指backend server響應HAProxy請求的超時時間
default域
上文所屬的frontend和backend域關鍵配置中,除acl、bind、http-request、http-response、use_backend外,其余的均可以配置在default域中。default域中配置了的項目,如果在frontend或backend域中沒有配置,將會使用default域中的配置。
listen域
listen域是frontend域和backend域的組合,frontend域和backend域中所有的配置都可以配置在listen域下
官方配置文檔
HAProxy的配置項非常多,支持非常豐富的功能,上文只列出了作為L7負載均衡器使用HAProxy時的一些關鍵參數。完整的參數說明請參見官方文檔 configuration.html
使用Keepalived實現HAProxy高可用
盡管HAProxy非常穩定,但仍然無法規避操作系統故障、主機硬件故障、網絡故障甚至斷電帶來的風險。所以必須對HAProxy實施高可用方案。
下文將介紹利用Keepalived實現的HAProxy熱備方案。即兩台主機上的兩個HAProxy實例同時在線,其中權重較高的實例為MASTER,MASTER出現問題時,另一台實例自動接管所有流量。
原理
在兩台HAProxy的主機上分別運行着一個Keepalived實例,這兩個Keepalived爭搶同一個虛IP地址,兩個HAProxy也嘗試去綁定這同一個虛IP地址上的端口。
顯然,同時只能有一個Keepalived搶到這個虛IP,搶到了這個虛IP的Keepalived主機上的HAProxy便是當前的MASTER。
Keepalived內部維護一個權重值,權重值最高的Keepalived實例能夠搶到虛IP。同時Keepalived會定期check本主機上的HAProxy狀態,狀態OK時權重值增加。
搭建HAProxy主備集群
- 環境准備
在兩台物理機上安裝並配置HAProxy,本例中,將在192.168.8.110和192.168.8.111兩台主機上上安裝兩套完全一樣的HAProxy,具體步驟省略,請參考“使用HAProxy搭建L7負載均衡器”一節。
- 安裝Keepalived
下載,解壓,編譯,安裝:
wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
tar -xzf keepalived-1.2.19.tar.gz
./configure --prefix=/usr/local/keepalived
make
make install
注冊為系統服務:
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
chmod +x /etc/init.d/keepalived
注意:Keepalived需要使用root用戶進行安裝和配置
- 配置Keepalived
創建並編輯配置文件
mkdir -p /etc/keepalived/
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
vi /etc/keepalived/keepalived.conf
配置文件內容:
global_defs {
router_id LVS_DEVEL #虛擬路由名稱
}
#HAProxy健康檢查配置
vrrp_script chk_haproxy {
script "killall -0 haproxy" #使用killall -0檢查haproxy實例是否存在,性能高於ps命令
interval 2 #腳本運行周期
weight 2 #每次檢查的加權權重值
}
#虛擬路由配置
vrrp_instance VI_1 {
state MASTER #本機實例狀態,MASTER/BACKUP,備機配置文件中請寫BACKUP
interface enp0s25 #本機網卡名稱,使用ifconfig命令查看
virtual_router_id 51 #虛擬路由編號,主備機保持一致
priority 101 #本機初始權重,備機請填寫小於主機的值(例如100)
advert_int 1 #爭搶虛地址的周期,秒
virtual_ipaddress {
192.168.8.201 #虛地址IP,主備機保持一致
}
track_script {
chk_haproxy #對應的健康檢查配置
}
}
如果主機沒有killall命令,則需要安裝psmisc包:
yum intall psmisc
- 分別啟動兩個Keepalived
service keepalived start
驗證
啟動后,先分別在兩台主機查看虛IP 192.168.8.201由誰持有,執行命令:
ip addr sh enp0s25 (將enp0s25替換成主機的網卡名)
持有虛IP的主機輸出會是這樣的:
另一台主機輸出則是這樣的:
如果你先啟動備機的Keepalived,那么很有可能虛IP會被備機搶到,因為備機的權重配置只比主機低1,只要執行一次健康檢查就能把權重提高到102,高於主機的101。
此時訪問http://192.168.8.201:9001/ms1/demo.html ,可以看到我們先前部署的網頁。
此時,檢查/var/log/haproxy.log,能看到此請求落在了搶到了虛IP的主機上。
接下來,我們停掉當前MASTER主機的HAProxy實例(或者Keepalive實例,效果一樣)
service haproxy stop
再次訪問http://192.168.8.201:9001/ms1/demo.html ,並查看備機的/var/log/haproxy.log,會看到此請求落在了備機上,主備自動切換成功。
也可以再次執行ip addr sh enp0s25命令,會看到虛IP被備機搶去了。
在/var/log/message中,也能夠看到keepalived輸出的切換日志: