
Web服務器動態水平擴展 --> 對用戶完全透明
提升業務并發處理能力 --> 有效解決單服務器性能瓶頸
優化公網IP資源 --> 顯著降低IT運營成本
保護內部服務器IP --> 增強系統安全性
簡易配置 --> 采用標準化配置文件格式
功能全面 --> 同時支持四層和七層協議,支持主機動態移除
高性能表現 --> 輕松應對數萬至數十萬并發請求
F5
- 美國F5網絡公司官網:F5 | 多云安全和應用交付
Netscaler
- 美國思杰公司產品頁面:NetScaler: Application Delivery at Scale
Array
- 華耀官網:北京華耀科技有限公司
AD-1000
- 深信服官網:深信服 - 讓每個用戶的數字化更簡單、更安全


HAProxy是由法國開發者威利塔羅(Willy Tarreau)于2000年使用C語言開發的開源軟件。
作為一款高性能負載均衡器,它支持TCP和HTTP協議,具備萬級以上的高并發處理能力。主要特性包括:
- 基于cookie的會話保持
- 自動故障轉移
- 正則表達式支持
- 實時Web狀態統計
資源鏈接:
- 企業版官網:HAProxy Technologies | Powering the World's Busiest Applications
- 社區版官網:http://www.haproxy.org
- GitHub倉庫:https://github.com/haprox

功能 | IP |
客戶端 | 172.25.254.111 |
haproxy | 172.25.254.100;192.168.0.10 |
RS1 | 172.25.254.10 |
RS2 | 172.25.254.20 |
dnf install haproxy -y
haproxy -v
軟件安裝包: haproxy-2.4.22-3.el9_3.x86_64.rpm
啟動文件: /lib/systemd/system/haproxy.service
主配置目錄: /etc/haproxy/
主配置文件: /etc/haproxy/haproxy.cfg
子配置目錄: /etc/haproxy/conf.d
vim /etc/haproxy/haproxy.cfg
# turn on stats unix socket
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
#啟用多個sock文件
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
nbproc 2
#啟用多進程
cpu-map 1 0
#進程和cpu核心綁定防止cpu抖動從而減少系統資源消耗
cpu-map 2 1
#2 表示第二個進程,1表示第二個cpu核心
systemctl start haproxy.service
pstree -p | grep haproxy
vim /etc/haproxy/haproxy.cfg
nbthread 2 #啟用多線程
systemctl restart haproxy.service
查看:
systemctl restart haproxy.service
cat /proc/xxxx(haproxy子進程id)/status
defaults
mode http #HAProxy實例使用的連接協議
log global #指定日志地址和記錄日志條目的
syslog/rsyslog日志設備
#此處的 global表示使用 global配置段中
設定的log值。
option httplog #日志記錄選項,httplog表示記錄與 HTTP
會話相關的各種屬性值
#包括 HTTP請求、會話狀態、連接數、源地
址以及連接時間等
option dontlognull #dontlognull表示不記錄空會話連接日志
option http-server-close #等待客戶端完整HTTP請求的時間,此處為等
待10s。
option forwardfor except 127.0.0.0/8 #透傳客戶端真實IP至后端web服務器
#在apache配置文件中加入:<br>%{XForwarded-For}i
#后在webserver中看日志即可看到地址透傳
信息
option redispatch #當server Id對應的服務器掛掉后,強制定
向到其他健康的服務器,重新派發
option http-keep-alive #開啟與客戶端的會話保持
retries 3 #連接后端服務器失敗次數
3.3.2.3 Proxies配置-frontend
frontend 配置參數:
frontend 配置示例:
timeout http-request 10s #等待客戶端請求完全被接收和處理的最長時
間
timeout queue 1m #設置刪除連接和客戶端收到503或服務不可
用等提示信息前的等待時間
timeout connect 120s #設置等待服務器連接成功的時間
timeout client 600s #設置允許客戶端處于非活動狀態,即既不發
送數據也不接收數據的時間
timeout server 600s #設置服務器超時時間,即允許服務器處于既
不接收也不發送數據的非活動時間
timeout http-keep-alive 60s #session 會話保持超時時間,此時間段內
會轉發到相同的后端服務器
timeout check 10s #指定后端服務器健康檢查的超時時間
maxconn 3000
default-server inter 1000 weight 3
systemctl restart haproxy.service
frontend lee-webserver-80
bind 172.25.254.100:80
mode http
use_backend lee-webserver-80-RS
backend lee-webserver-80-RS
mode http
server web1 172.25.254.10:80 check inter 3s fall 3 rise 5
server web2 172.25.254.20:80 check inter 3s fall 3 rise 5
systemctl restart haproxy.service
測試:
在RS1,RS2安裝nginx:
dnf install nginx -y
開啟:
systemctl start nginx
在網頁文檔中寫入內容:
#寫在RS1
echo RS1 -172.25.254.10 > /usr/share/nginx/html/index.html
#寫在RS2
echo RS2 -172.25.254.20 > /usr/share/nginx/html/index.html
在客戶端測試:
for N in {1..6};do curl 172.25.254.100;done
99 listen webserver
100 bind *:80
101 mode http
102 balance static-rr
103 server webserver1 172.25.254.10:80 check inter 3s fall 3 weight 2
104 server webserver2 172.25.254.20:80 check inter 3s fall 3 weight 2

systemctl restart haproxy.service
客戶端測試:
for N in {1..6};do curl 172.25.254.100;done
dnf install socat -y
修改配置文件:
vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/stats mode 600 level adminsystemctl restart haproxy.service
socat -h
echo "help" | socat stdio /var/lib/haproxy/stats
echo "show info" | socat stdio /var/lib/haproxy/stats
echo "show servers state" | socat stdio /var/lib/haproxy/stats
echo get weight webserver/web1 | socat stdio /var/lib/haproxy/stats
echo set weight webserver/web1 1 | socat stdio /var/lib/haproxy/stats
echo "disable server webserver/web1 " | socat stdio /var/lib/haproxy/stats
上線:
echo "enable server webserver/web1 " | socat stdio /var/lib/haproxy/stats
vim /etc/haproxy/haproxy.cfg
...上面內容省略...
listen stats
mode http
bind *:1616
stats enable
log global
stats uri /haproxy-status
stats auth lee:lee
while true;do curl 172.25.254.100 ; sleep 0.1;done







echo "set weight webserver_80/webserver1 2" | socat stdio /var/lib/haproxy/haproxy.sock




?原理一句話總結
用 源地址(source IP) 做哈希,再 對總權重取模,決定轉發到哪臺后端服務器。
?優點
-
實現簡單,計算快。
-
請求分布均勻,能做到較好的負載均衡。
-
無狀態,不依賴歷史連接或會話。
?缺點
-
靜態調度:一旦后端服務器數量或權重變化,所有哈希結果都會重新分布。
-
也就是說:上線/下線一臺機器,所有連接都會被打亂重排。
-
-
不支持:
-
動態權重調整(不能在線改權重)
-
慢啟動(slow-start)
-
會話保持(除非用一致性哈希)
-
?舉個例子
假設有三臺后端服務器,權重分別為:
-
A:3
-
B:2
-
C:1
總權重 = 6
一個客戶端 IP 哈希后得 17,則:
17 % 6 = 5
根據權重區間劃分:
-
A:0~2
-
B:3~4
-
C:5
→ 請求會打到 C。
如果此時 C 下線,總權重變成 5,那么:
17 % 5 = 2
現在會打到 A,之前打到 C 的所有請求都變了。
?總結一句話
取模哈希法簡單高效,但服務器變化會導致“全量重排”,不適合對穩定性要求高的業務。
?替代方案
-
一致性哈希調度(consistent hashing):服務器增減只影響局部請求,避免全量重排。
-
加權輪詢(WRR)或 最少連接數(LC):支持動態權重和慢啟動。

#不支持動態調整權重值
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio
/var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
#只能動態上線和下線
[root@haproxy ~]# echo "set weight webserver_80/webserver1 0" | socat stdio
/var/lib/haproxy/haproxy.sock
[root@haproxy ~]# echo "get weight webserver_80/webserver1" | socat stdio
/var/lib/haproxy/haproxy.sock
0 (initial 1)
-
基本概念
? 傳統取模:hash(o) mod n
服務器數量 n 一變,所有結果重新洗牌 → 命中率雪崩。
? 一致性哈希:把服務器和對象都映射到 0~232 的「Hash 環」上。
對象順時針找最近的服務器。
服務器數量變化時,只影響環上相鄰的一小段 → 局部重映射。
-
環偏斜(Skew)與虛擬節點
? 問題:真實節點在環上可能分布不均,導致負載不均。
? 解決:每個物理節點拆成 w × k 個「虛擬節點」
HAProxy 中叫 id
,Nginx 中叫 weight
× consistent
參數。
虛擬節點越多,分布越均勻,但 CPU 略增。








curl 172.25.254.100/index.html?name=aaa



-
一句話解釋
HAProxy 先看你指定的 HTTP 頭字段(比如 User-Agent
、X-Real-IP
、X-Api-Key
等),
把這個頭的值做 hash → 再按 服務器總權重取模 → 決定把請求扔給哪臺后端。
? 頭字段存在 → 用 hash 結果挑服務器(靜態映射)。
? 頭字段不存在 → 退化成普通輪詢(round-robin)。
-
為什么用它
? 同一客戶端或同一類客戶端 始終落到同一臺機器(會話粘滯、緩存親和)。
? 頭字段變化少,hash 結果就穩定,命中率高。
? 支持在線調權重(一致性哈希版本),也支持慢啟動。

curl -v 172.25.254.100

curl -vA "firefox" 172.25.254.100
#靜態
static-rr--------->tcp/http
first------------->tcp/http
#動態
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
#以下靜態和動態取決于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
first #使用較少
static-rr #做了session共享的web集群
roundrobin
random
leastconn #數據庫
source
#基于客戶端公網IP的會話保持
Uri--------------->http #緩存服務器,CDN服務商,藍汛、百度、阿里云、騰訊
url_param--------->http #可以實現session保持
hdr #基于客戶端請求報文頭部做下一步處理
(在響應里給客戶端 種一個特定 cookie,以后客戶端每次帶著這個 cookie 來,HAProxy 就根據 cookie 值把請求 精確地送回上一次那臺后端,實現會話黏著(sticky session)。)
】


curl -i 172.25.254.100
curl -b WEBCOOKIE=web1 172.25.254.100

curl -vb WEBCOOKIE=web1 172.25.254.100
listen statsmode httpbind *:1616stats enablelog globalstats uri /statusstats auth xyz:xyz

http://172.25.254.100:1616/status


vim /etc/nginx/nginx.conf

tail -n 3 /var/log/nginx/access.log
' "$proxy_protocol_addr"'80 proxy_protocol; #啟用此項,將無法直接訪問此網站,只能通過四層代理
vim /etc/nginx/nginx.conf
systemctl restart nginx


tail -n 3 /var/log/nginx/access.log
vim /etc/haproxy/haproxy.cfg

LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined





dnf install php -y
vim /usr/share/nginx/html/index.php<?phpphpinfo();
?>

[root@rs1 ~]# mkdir /usr/share/nginx/html/static
[root@rs1 ~]# echo static 192.168.0.101 > /usr/share/nginx/html/static/index.html
測試:


[root@haproxy ~]# mkdir /haproxy/errorpages/ -p
[root@haproxy ~]# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
[root@haproxy ~]# vim /haproxy/errorpages/503page.http



listen mysql_port
bind :3306
mode tcp
balance leastconn
server mysql1 192.168.0.101:3306 check
server mysql2 192.168.0.102:3306 check

yum install mariadb-server -yvim /etc/my.cnf[mysqld]
server-id=1 #在另一臺主機為[mysqld]
server-id=2 #在另一臺主機為
mysql -e "grant all on *.* to lee@'%' identified by 'lee';"
客戶端測試:
mysql -ulee -plee -h 172.25.254.100 -e "show variables like
'hostname'"
mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
mkdir /etc/haproxy/certs/
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
cat /etc/haproxy/certs/timinglee.org.crt \/etc/haproxy/certs/timinglee.org.key \> /etc/haproxy/timinglee.org.pem
frontend webserver
bind *:80
redirect scheme https if !{ ssl_fc }
mode http
use_backend webcluster
frontend webserver-https
bind *:443 ssl crt /etc/haproxy/timinglee.org.pem
mode http
use_backend webcluster
backend webcluster
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 3s fall 3 rise 5
server web2 172.25.254.20:80 check inter 3s fall 3 rise 5
curl -IkL http://172.25.254.100
haproxy -c -f /etc/haproxy/haproxy.cfg