前言:
????????在現代分布式系統中,負載均衡和高可用性是保障服務穩定性和性能的關鍵技術。HAProxy 作為一款高性能的 TCP/HTTP 負載均衡器,憑借其輕量級、高并發處理能力和靈活的配置機制,成為構建高可用架構的核心組件之一。通過智能的流量分發和健康檢查機制,HAProxy 能夠有效提升系統的吞吐能力,同時避免單點故障,確保服務持續可用。本文將簡要概述 HAProxy 如何實現負載均衡及高可用,并探討其在實際場景中的應用價值。
目錄
1、HAProxy簡介
2、HAProxy特點和優點:
3、HAProxy保持會話的三種解決方法
4、HAProxy的balance 8種負載均衡算法
1)RR(Round Robin)
2)LC(Least Connections)
3)SH(Source Hashing)
4)uri(資源標識符)
5)url_param(資源定位符)
7) source
8) static-rr
5、HAProxy 主要工作模式
6、HAProxy配置文件參數
6.1、HAProxy 環境
6.1.1、 global 全局配置
6.1.2、 proxy 代理配置
proxies 配置-defaults
7、狀態統計功能測試
總結
1、HAProxy簡介
官網:HAProxy Technologies | Powering the World's Busiest Applications
HAProxy 是法國人Willy Tarreau開發的一個開源軟件,是一款應對客戶端10000以上的同時連接的高性能的TCP和 HTTP負載均衡器。其功能是用來提供基于cookie的持久性, 基于內容的交換,過載保護的高級流量管制,自動故障切換 ,以正則表達式為基礎的標題控制運行時間,基于Web的報表,高級日志記錄以幫助排除故障的應用或網絡及其他功能。
HAProxy 提供高可用性、負載均衡以及基于TCP和HTTP的應用代理,支持虛擬主機,它是免費、快速并且可靠的一種負載均衡解決方案。適合處理高負載站點的 七層 數據請求。類似的代理服務可以屏蔽內部真實服務器,防止內部服務器遭受攻擊。
2、HAProxy特點和優點:
-
支持原生SSL,同時支持客戶端和服務器的SSL.
-
支持IPv6和UNIX套字節(sockets)
-
支持HTTP Keep-Alive
-
支持HTTP/1.1壓縮,節省寬帶
-
支持優化健康檢測機制(SSL、scripted TCP、check agent…)
-
支持7層負載均衡。
-
可靠性和穩定性非常好。
-
并發連接 40000-50000個,單位時間處理最大請求 20000個,最大數據處理10Gbps.
-
支持8種負載均衡算法,同時支持session保持。
-
支持虛擬主機。
-
支持連接拒絕、全透明代理。
-
擁有服務器狀態監控頁面。
-
支持ACL(access control list)。
3、HAProxy保持會話的三種解決方法
HAProxy為了讓同一客戶端訪問服務器可以保持會話。有三種解決方法:客戶端IP、Cookie以及Session。
-
通過 客戶端IP 進行Hash計算并保存,以此確保當相同IP訪問代理服務器可以轉發給固定的真實服務器。
-
依靠真實服務器發送客戶端的 Cookie信息 進行會話保持。
-
將保存真實服務器的 Session 以及服務器標識 ,實現會話保持。
(HAProxy只要求后端服務器能夠在網絡聯通,也沒有像LVS那樣繁瑣的ARP配置)
4、HAProxy的balance 8種負載均衡算法
1)RR(Round Robin)
RR算法是最簡單最常用的一種算法,即輪詢調度
理解舉例:有三個節點A、B、C
第一個用戶訪問會被指派到節點A
第二個用戶訪問會被指派到節點B
第三個用戶訪問會被指派到節點C
第四個用戶訪問繼續指派到節點A,輪詢分配訪問請求實現負載均衡效果
2)LC(Least Connections)
最小連接數算法,根據后端的節點連接數大小動態分配前端請求
理解舉例: 有三個節點A、B、C,各節點的連接數分別為A:4 B:5 C:6
第一個用戶連接請求,會被指派到A上,連接數變為A:5 B:5 C:6
第二個用戶請求會繼續分配到A上,連接數變為A:6 B:5 C:6;再有新的請求會分配給B,每次將新的請求指派給連接數最小的客戶端
由于實際情況下A、B、C的連接數會動態釋放,很難會出現一樣連接數的情況
此算法相比較rr算法有很大改進,是米錢用到比較多的一種算法
3)SH(Source Hashing)
基于來源訪問調度算法,用于一些有Session會話記錄在服務端的場景,可以基于來源的IP、Cookie等做集群調度
理解舉例 有三個節點A、B、C,第一個用戶第一次訪問被指派到了A,第二個用戶第一次訪問被指派到了B
當第一個用戶第二次訪問時會被繼續指派到A,第二個用戶第二次訪問時依舊會被指派到B,只要負載均衡器不重啟,第一個用戶都會被指派到A,第二個用戶訪問都會被指派到B,實現集群的調度
此調度算法好處是實現會話保持,但某些IP訪問量非常大時會引起負載不均衡,部分節點訪問量超大,影響業務使用
4)uri(資源標識符)
表示根據請求的URI,做cdn(內容分發網絡)需使用
5)url_param(資源定位符)
表示根據HTTP請求頭來鎖定每 一 次HTTP請求。
6)rdp—cookie(name)
表示根據據cookie (name)來鎖定并哈希每一次TCP請求。
7) source
表示根據請求的源IP,類似Nginx的IP hash機制。
8) static-rr
表示根據權重,輪詢
5、HAProxy 主要工作模式
tcp模式:在客戶端和服務器之間將建立一個全雙工的連接,且不會對7層的報文做任何處理的簡單模式。 通常用于SSL、SSH、SMTP等應用層。
http模式(一般使用):客戶端請求在轉發給后端服務器之前會被深度分析,所有不與RFC格式兼容的請求都會被拒絕。
6、HAProxy配置文件參數
6.1、HAProxy 環境
haproxy的配置文件 haproxy.cfg 的 默認地址:/etc/haproxy/haproxy.cfg 。
haproxy.cfg 由兩大部分組成,分別是 global 和 proxies 部分。
global:全局配置:
?進程及安全配置相關的參數性能調整相關參數Debug參數
proxies:代理配置
?defaults:為 frontend, backend, listen提供默認配置frontend:前端,相當于 nginx 中的 server {}backend:后端,相當于 nginx 中的 upstream {}listen:同時擁有 前端和后端配置
名稱說明:
-
frontend 端(front end):指定接收 客戶端 偵聽套接字設置。
-
backend 端(back end):指定將連接請求轉發至 后端服務器 的相關設置。
-
listen 端:指定完整的前后端設置,只對TCP有效 。
-
proxy 名稱:使用字母 、數字 - 、_ 、. 、: ,并區分字符大小寫。
6.1.1、 global 全局配置
?chroot ? ? ? ? ? ? ? ? ? # 鎖定運行目錄deamon ? ? ? ? ? ? ? ? ? # 以守護進程運行stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin ? ?# socket文件user, group, uid, gid ? ? # 運行haproxy的用戶身份nbproc ? ? ? ? ? ? ? ? ? ?# 開啟的haproxy進程數,與CPU保持一致nbthread ? ? ? ? ? ? ? ? ?# 指定每個haproxy進程開啟的線程數,默認為每個進程一個線程cpu-map 1 0 ? ? ? ? ? ? ? # 綁定haproxy 進程至指定CPUmaxconn ? ? ? ? ? ? ? ? ? # 每個haproxy進程的最大并發連接數maxsslconn ? ? ? ? ? ? ? ?# 每個haproxy進程ssl最大連接數,用于haproxy配置了證書的場景下maxconnrate ? ? ? ? ? ? ? # 每個進程每秒創建的最大連接數量spread-checks ? ? ? ? ? ? # 后端server狀態check隨機提前或延遲百分比時間,建議2-5(20%-50%)之間pidfile ? ? ? ? ? ? ? ? ? # 指定pid文件路徑log 127.0.0.1 local3 info ? ?# 定義全局的syslog服務器;最多可以定義兩個
示例:
?######################## 全局配置 ############################ ####### 參數是進程級的,通常和操作系統(OS)相關global chroot /var/haproxy ? ? ? ? ? ? # 鎖定運行目錄uid 99 ? ? ? ? ? ? ? ? ? ? ? ? ?# 所屬運行的用戶uid gid 99 ? ? ? ? ? ? ? ? ? ? ? ? ?# 所屬運行的用戶組 daemon ? ? ? ? ? ? ? ? ? ? ? ? ?# 守護進程。以后臺形式運行haproxy nbproc 1 ? ? ? ? ? ? ? ? ? ? ? ?# haproxy進程數,與CPU保持一致pidfile /var/run/haproxy.pid ? ?# haproxy的pid存放路徑,啟動進程的用戶必須有權限訪問此文件 ulimit-n 65535 ? ? ? ? ? ? ? ? ?# ulimit的數量限制maxconn 20480 ? ? ? ? ? ? ? ? ? # 默認最大連接數 log 127.0.0.1 local0 ? ? ? ? ? ?# 日志輸出配置,所有日志都記錄在本機系統日志,通過 local0 輸出log 127.0.0.1 local1 notice ? # notice 為日志級別,通常有24個級別(error warring info debug)
6.1.2、 proxy 代理配置
主要分為下面4個部分
?defaults [<name>] ?# 默認配置項,針對以下的frontend、backend和lsiten生效,可以多個namefrontend <name> ? ?# 前端servername,類似于Nginx的一個虛擬主機 server。backend <name> ? ? # 后端服務器組,等于nginx的upstreamlisten <name> ? ? ?# 將frontend和backend合并在一起配置
proxies 配置-defaults
option redispatch ? ? ? ? ? # 當server Id對應的服務器掛掉后,強制定向到其他健康的服務器option abortonclose ? ? ? ? # 當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接option http-keep-alive ? ? ?# 開啟與客戶端的會話保持option forwardfor ? ? ? ? ? # 透傳客戶端真實IP至后端web服務器mode http ? ? ? ? ? ? ? ? ? # 默認工作類型timeout connect 120s ? ? ? ?# 客戶端請求到后端server的最長連接等待時間(TCP之前)timeout server 600s ? ? ? ? # 客戶端請求到后端服務端的超時超時時長(TCP之后)timeout client 600s ? ? ? ? # 與客戶端的最長非活動時間timeout http-keep-alive 120s # session 會話保持超時時間,范圍內會轉發到相同的后端服務器timeout check 5s ? ? ? ? ? ?# 對后端服務器的檢測超時時間
示例:
?######################### 默認設置 ########################## ## 這些參數可以被利用配置到 frontend,backend,listen組件defaults log global ? ? ? ? ? ? ? ? ? ? ?# 定義日志為global(全局)配置中的日志定義mode http ? ? ? ? ? ? ? ? ? ? ? # 所處理的類別 (網絡七層協議中,tcp是第4層的會話層、http是第7層的應用層) maxconn 20480 ? ? ? ? ? ? ? ? ? # 最大連接數 option httplog ? ? ? ? ? ? ? ? ?# 日志類別http日志格式 option httpclose ? ? ? ? ? ? ? ?# 每次請求完畢后主動關閉http通道 option dontlognull ? ? ? ? ? ? ?# 不記錄健康檢查的日志信息 option forwardfor ? ? ? ? ? ? ? # 如果后端服務器需要獲得客戶端真實ip需要配置的參數,可以從Http Header中獲得客戶端ip ?option redispatch ? ? ? ? ? ? ? # 當server Id對應的服務器掛掉后,強制定向到其他健康的服務器option abortonclose ? ? ? ? ? ? # 當服務器負載很高的時候,自動結束掉當前隊列處理比較久的連接 stats refresh 30 ? ? ? ? ? ? ? ?# 統計頁面刷新間隔 retries 3 ? ? ? ? ? ? ? ? ? ? ? # 檢查節點服務器失敗次數,連續達到三次失敗,則認為節點不可用balance roundrobin ? ? ? ? ? ? ?# 默認的負載均衡的方式,輪詢方式,上面的第4段8種負載均衡算法#balance source ? ? ? ? ? ? ? ? # 默認的負載均衡的方式,類似nginx的ip_hash #balance leastconn ? ? ? ? ? ? # 默認的負載均衡的方式,最小連接 contimeout 5000 ? ? ? ? ? ? ? ? # 連接的超時時間clitimeout 50000 ? ? ? ? ? ? ? ?# 客戶端的超時時間srvtimeout 50000 ? ? ? ? ? ? ? ?# 服務器的超時時間timeout check 2000 ? ? ? ? ? ? ?# 心跳檢測的超時時間
7、狀態統計功能測試
下載haproxy
yum -y install haproxy
修改配置文件
[root@haproxy ~]# cd /etc/haproxy/
[root@haproxy haproxy]# ls
conf.d haproxy.cfg
[root@haproxy haproxy]# vim haproxy.cfg
[root@haproxy haproxy]# cat haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------globallog 127.0.0.1 local2chroot /var/lib/haproxypidfile /var/run/haproxy.piduser haproxygroup haproxydaemonmaxconn 4000defaultsmode httplog globaloption httplogoption dontlognullretries 3timeout http-request 5stimeout queue 1mtimeout connect 5stimeout client 1mtimeout server 1mtimeout http-keep-alive 5stimeout check 5smaxconn 3000frontend mainbind *:80default_backend http_backbackend http_backbalance roundrobinserver node1 192.168.72.164:80 check ###web1主機IP地址server node2 192.168.72.165:80 check ###web2主機IP地址
listen stats #定義監控頁面 mode httpoption httplogbind *:1080 #綁定端口1080 stats refresh 30s #每30秒更新監控數據 stats uri /stats #訪問監控頁面的uri stats realm HAProxy\ Stats #監控頁面的認證提示 stats auth admin:admin #監控頁面的用戶名和密碼
web1、web2下載并開啟nginx
[root@web1 ~]# yum install -y nginx
[root@web1 ~]# systemctl start nginx[root@web2 ~]# yum install -y nginx
[root@web2 ~]# systemctl start nginx
web1、web2在Nginx web服務器的默認根目錄下的首頁文件中輸入內容
[root@web1 ~]# echo web1 > /usr/share/nginx/html/index.html
[root@web2 ~]# echo web2 > /usr/share/nginx/html/index.html
回到haproxy開啟haproxy.service
[root@haproxy ~]# systemctl start haproxy.service#查看監聽
[root@haproxy ~]# netstat -antup | grep 80
tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN 10525/haproxy
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10525/haproxy
驗證流量分發?
訪問192.168.72.163web網站,查看到請求被均勻地分發到了兩個不同的后端服務器(web1和web2),采用輪詢實現負載均衡策略
訪問192.168.72.163:1080/stats web網站,輸入用戶名:admin,密碼:admin,進入狀態統計頁面
HAProxy + Keepalived實現負載均衡高可用
主機 | 作用 | 真實 IP (RIP) | 虛擬 IP (VIP) |
---|---|---|---|
?server1? | 主負載均衡節點 | 192.168.72.163 | 192.168.72.100 |
?server2? | 備負載均衡節點 | 192.168.72.185 | 192.168.72.100 |
?Web1 | 后端服務器 1 | 192.168.72.164 | - |
?Web2 | 后端服務器 2 | 192.168.72.165 | - |
客戶端請求↓
[ VIP: 192.168.72.100 ] ← Keepalived 主備切換 (server1/server2)↓
[ HAProxy 負載均衡 ]↓
[ web1:192.168.72.164 ]
[ web2:192.168.72.165 ]
server1主節點修改配置文件/etc/keepalived/keepalived.conf
server2備節點修改配置文件/etc/keepalived/keepalived.conf
server1備節點修改配置文件/etc/haproxy/haproxy.cfg
[root@server1 ~]# cat /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------globallog 127.0.0.1 local2chroot /var/lib/haproxypidfile /var/run/haproxy.piduser haproxygroup haproxydaemonmaxconn 4000defaultsmode httplog globaloption httplogoption dontlognullretries 3timeout http-request 5stimeout queue 1mtimeout connect 5stimeout client 1mtimeout server 1mtimeout http-keep-alive 5stimeout check 5smaxconn 3000frontend http-inbind 192.168.72.100:80default_backend web_serversbackend web_serversbalance roundrobinserver web1 192.168.72.164:80 checkserver web2 192.168.72.165:80 check
server2備節點修改配置文件/etc/haproxy/haproxy.cfg
[root@server2 haproxy]# cat haproxy.cfg
#---------------------------------------------------------------------
# Example configuration for a possible web application. See the
# full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------globallog 127.0.0.1 local2chroot /var/lib/haproxypidfile /var/run/haproxy.piduser haproxygroup haproxydaemonmaxconn 4000defaultsmode httplog globaloption httplogoption dontlognullretries 3timeout http-request 5stimeout queue 1mtimeout connect 5stimeout client 1mtimeout server 1mtimeout http-keep-alive 5stimeout check 5smaxconn 3000frontend http-inbind 192.168.72.100:80default_backend web_serversbackend web_serversbalance roundrobinserver web1 192.168.72.164:80 checkserver web2 192.168.72.165:80 check
啟動服務?
###在兩臺server上執行:
systemctl start keepalived
systemctl start haproxy###備節點需要強制切換VIP到備節點開啟服務(測試)
[root@server2 haproxy]# ip addr add 192.168.72.100/24 dev ens33
[root@server2 haproxy]# systemctl restart haproxy
server1、server2分別輸入ip a命令查看確保 Keepalived 主節點 server1 應持有 VIP,備節點 server2 現未持有VIP,在故障時接管
[root@server1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:c2:74:d2 brd ff:ff:ff:ff:ff:ffinet 192.168.72.163/24 brd 192.168.72.255 scope global dynamic noprefixroute ens33valid_lft 1324sec preferred_lft 1324secinet 192.168.72.100/24 scope global secondary ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fec2:74d2/64 scope link noprefixroute valid_lft forever preferred_lft forever###
[root@server2 haproxy]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:9b:f9:1b brd ff:ff:ff:ff:ff:ffinet 192.168.72.185/24 brd 192.168.72.255 scope global dynamic noprefixroute ens33valid_lft 1685sec preferred_lft 1685secinet6 fe80::20c:29ff:fe9b:f91b/64 scope link noprefixroute valid_lft forever preferred_lft forever
驗證流量分發
訪問192.168.72.100web站點,在后端web1、web2上部署不同頁面分別返回 web1和web2內容,說明輪詢策略生效,實現負載均衡
故障模擬
VIP飄逸測試
切換到server1關閉Keepalived
[root@server1 ~]# systemctl stop keepalived###查看服務狀態
[root@server1 ~]# systemctl status keepalived
○ keepalived.service - LVS and VRRP High Availability MonitorLoaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; preset: disabled)Active: inactive (dead)7月 16 10:34:42 server1 systemd[1]: Stopping LVS and VRRP High Availability Monitor...
7月 16 10:34:42 server1 Keepalived[26286]: Stopping
7月 16 10:34:42 server1 Keepalived_vrrp[26287]: (VI_1) sent 0 priority
7月 16 10:34:42 server1 Keepalived_vrrp[26287]: (VI_1) removing VIPs.
7月 16 10:34:43 server1 Keepalived_vrrp[26287]: Stopped - used 0.000000 user time, 0.069239 system time
7月 16 10:34:43 server1 Keepalived[26286]: CPU usage (self/children) user: 0.000000/0.000000 system: 0.000834/0.069811
7月 16 10:34:43 server1 Keepalived[26286]: Stopped Keepalived v2.2.8 (04/04,2023), git commit v2.2.7-154-g292b299e+
7月 16 10:34:43 server1 keepalived-stop-post.sh[30523]: Excuted stop-post keepalived
7月 16 10:34:43 server1 systemd[1]: keepalived.service: Deactivated successfully.
7月 16 10:34:43 server1 systemd[1]: Stopped LVS and VRRP High Availability Monitor.
此時在server2主機輸入ip a命令觀察VIP已漂移到server2,實現故障轉移
[root@server2 haproxy]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:9b:f9:1b brd ff:ff:ff:ff:ff:ffinet 192.168.72.185/24 brd 192.168.72.255 scope global dynamic noprefixroute ens33valid_lft 1209sec preferred_lft 1209secinet 192.168.72.100/24 scope global secondary ens33valid_lft forever preferred_lft foreverinet6 fe80::20c:29ff:fe9b:f91b/64 scope link noprefixroute valid_lft forever preferred_lft forever
此時再次訪問192.168.72.100web站點保持正常,因備節點自動接管,
總結:
????????HAProxy 通過多節點流量調度、健康監測和故障自動轉移等機制,不僅實現了高效的負載均衡,還大幅提升了系統的容錯能力。無論是應對高并發請求,還是保障關鍵業務的高可用性,HAProxy 都展現出了強大的適應性和可靠性。結合合理的架構設計(如多活部署、會話保持等),HAProxy 能夠為企業級應用提供穩定、高效的流量管理解決方案,成為現代云原生和微服務架構中不可或缺的基礎設施組件。