一、概念
HAProxy(High?Availability?Proxy)是一款開源的高性能?TCP/HTTP 負載均衡器?和?反向代理?軟件,被廣泛應用于構建高可用、高并發的現代網絡架構。
核心功能:
負載均衡(Load Balancing)
支持四層(TCP)和七層(HTTP/HTTPS)流量分發。
提供多種調度算法:輪詢(
roundrobin
)、最少連接(leastconn
)、源IP哈希(source
)等。
反向代理(Reverse Proxy)
隱藏后端服務器細節,對外提供統一入口。
支持 SSL 終端(SSL Termination),卸載后端服務器加密負擔。
高可用(High Availability)
結合 Keepalived 實現雙機熱備(VRRP 協議)。
流量治理
請求過濾、速率限制、連接控制等。
多層級負載均衡
層級 | 協議支持 | 典型場景 |
---|---|---|
四層(L4) | TCP/UDP | 數據庫集群、Redis、SSH 跳板 |
七層(L7) | HTTP/HTTPS/HTTP2/3 | Web 應用、API 網關、微服務路由 |
與 Nginx/LVS 對比
特性 | HAProxy | Nginx | LVS |
---|---|---|---|
協議支持 | ★★★ (TCP/HTTP/SSL) | ★★★ (HTTP/SSL) | ★★ (TCP/UDP) |
七層能力 | ★★★ (ACL/重寫/緩存) | ★★★ | ? (僅四層) |
性能 | ★★★ (L4/L7 均優) | ★★ (HTTP 強) | ★★★ (L4 極致) |
配置靈活性 | ★★★ (DSL 語法) | ★★ (類 C 配置) | ★ (ipvsadm 命令行) |
健康檢查 | ★★★ (多協議支持) | ★★ | ★ (基礎 TCP 檢查) |
二、實驗
1、實驗環境的搭建
準備3臺主機:
主機1
主機名:haproxy
ip:172.25.254.100
主機2
主機名:hp-RS1
ip:172.25.254.10
主機3
主機名:hp-RS2
ip:172.25.254.20
(1)軟件包安裝
兩臺RS都安裝nginx:
設置開機自啟動(兩個都設置)
(2)關閉火墻
兩臺RS關閉火墻:
(3)兩臺RS設置nginx的index.html內容
設置這個是方便后續測試
(4)連通測試
haproxy主機curl一下兩臺RS?
連接成功
實驗環境搭建完畢
(5)方便碼字的tab鍵設置
2、haproxy的安裝和frontend區
(1)安裝haproxy
dnf安裝
??
啟動服務
(2)進入haproxy配置文件
進入編寫
wq
重啟服務
3、global配置(多進程與多線程)
(1)global配置參數解釋
配置區域在/etc/haproxy/haproxy.conf的global區
參數 | 說明 | 示例 | 必要性 |
---|---|---|---|
daemon | 以守護進程(后臺)模式運行 | daemon | ? 生產必選 |
user group | 指定運行用戶/用戶組(降權運行) | user haproxy group haproxy | ? 安全必選 |
chroot | 切換根目錄(增強安全性) | chroot /var/lib/haproxy | ?? 可選 |
nbproc | 工作進程數(CPU 核數綁定) | nbproc 4 | ?? 高并發必選 |
nbthread | 每進程線程數(需啟用線程) | nbthread 2 | ?? 現代 CPU 優化 |
stats socket | 管理套接字路徑(動態調整配置) | stats socket /run/haproxy/admin.sock | ?? 運維必選 |
(2)多進程與多線程
1)多進程(nbproc)
開啟多進程則進入haproxy的配置文件
wq
解釋:
- nbproc 2 —— 啟用多進程,2個進程
- cpu-map 1 0 ——??進程和cpu核心綁定防止cpu抖動從而減少系統資源消耗,1表示指定第一個work綁定第一個核心,0表示第一個核心,核心從0開始算(類似數組下標)
- cpu-map 2 1 —— 指定第二個work綁定第二個cpu核心
重啟服務
2)多線程(nbthread)
開啟多線程也是進入haproxy的配置文件
wq?
解釋:
nbthread —— 啟動多線程,線程數為2?
多線程和多進程只能存在一個,另一個要#號引掉
查看多線程
[root@haproxy ~]# cat /proc/1653/status
數字1653是剛剛查看的進程id
未開啟前,thread為1
而修改完,重啟服務后
重啟服務后,要先pstree才有進程id哦
thread變為2?
?
這就是多線程
4、socat工具
socat
?是 HAProxy 生態中不可替代的底層診斷工具,它通過直接訪問 HAProxy 的?Unix 管理套接字實現高級運維操作。
為什么需要?socat
?
場景 | 傳統方案痛點 | socat 解決方案 |
---|---|---|
動態服務器狀態調整 | 需重載配置(中斷連接) | 實時啟用/禁用服務器(零中斷) |
緊急故障屏蔽 | 修改配置+重載耗時 >30s | 1秒內下線故障節點 |
內存泄漏分析 | 依賴外部監控工具 | 直接dump進程內存結構 |
流診斷 | 抓包分析復雜 | 實時鏡像指定流量 |
(1)安裝
dnf安裝socat
(2)修改配置文件
進入haproxy配置文件:
進入編輯:
(3)常用示例
1)查看haproxy狀態
echo "show info" | socat stdio /var/lib/haproxy/stats
2)?查看集群狀態
echo "show servers state" | socat stdio /var/lib/haproxy/stats
3)查看集群權重
echo get weight webcluster/web1 | socat stdioecho get weight webcluster/web2 | socat stdio
4)設置權重
echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats
可以查看一下設置成功沒:
成功
5)下線后端服務器
echo "disable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats
6)上線后端服務器
echo "enable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats
5、haproxy算法?
(1)static-rr
原理:?也是輪詢算法,但不支持運行時權重動態調整。
權重支持:?支持,但權重在啟動時確定后,在運行時無法通過運行時 API 動態修改(而?
roundrobin
?可以)。特點:?比?
roundrobin
?稍簡單一些,開銷略低。如果確定不需要在運行時動態調整權重,可以使用此算法。
static-rr不支持熱更新:
?測試
(2)first
原理:?按照服務器在配置文件中聲明的順序進行分配。將請求分配給列表中第一個可用的服務器。僅當第一個服務器達到其最大連接數 (
maxconn
) 時,才會分配給下一個可用的服務器。?一旦某個服務器連接數降到?maxconn
?以下,新請求又會優先分配給它。權重支持:?不支持。
特點:?盡量將流量集中到列表前面的服務器,直到它們滿載。可能導致負載分布非常不均衡,前面的服務器壓力很大,后面的服務器很空閑。
?
測試
都是RS1,因為要等RS1滿了,才會輪到到RS2
(3)roundrobin
原理:?最常用、最經典的輪詢算法。按順序依次將新請求分配給后端服務器列表中的下一個服務器。循環往復。
權重支持:?支持。服務器可以配置權重 (
weight
)。權重高的服務器在輪詢周期內會獲得更多比例的請求。特點:?簡單、公平、可預測。在服務器性能相近且請求處理時間相對均勻時效果很好。
測試
標準的輪詢
(4)leastconn
原理:?最少連接數算法。?將新請求分配給當前活躍連接數最少的后端服務器。
權重支持:?支持。計算時會考慮權重。實際比較的是?
(當前連接數) / (權重)
。值最小的服務器勝出。權重高的服務器能承受更多連接。特點:?非常適合處理時間差異很大的請求(例如數據庫連接、長連接應用如 WebSocket、消息隊列)。能更公平地根據服務器實際處理能力分配負載。
測試?
和輪詢差不多
(5)source
原理:?源 IP 地址哈希。?使用客戶端的源 IP 地址計算哈希值,決定分配到哪個后端服務器。
權重支持:?不支持。哈希結果直接映射到服務器,權重不影響哈希分配本身(但影響服務器池的組成)。
特點:?確保來自同一個客戶端的請求總是落到同一臺服務器(只要服務器池不變)。簡單但不夠靈活,如果客戶端使用代理或 NAT,大量不同用戶可能共享同一個源 IP,導致負載不均衡。
測試
(6)uri
原理:?整個 URI 哈希。?使用 HTTP 請求的完整 URI(包括路徑和查詢參數,例如?
/path/page?param=value
)計算哈希值。權重支持:?不支持。
特點:?將訪問相同 URI 的請求固定到同一服務器。有助于利用服務器本地的緩存(如果緩存是基于 URI 的)。
測試
(7)url-param
原理:?URL 參數值哈希。?使用 HTTP 請求 URL 中指定的查詢字符串參數的值計算哈希值。需要配置參數名(例如?
url_param userid
)。權重支持:?不支持。
特點:?非常靈活,可以根據業務關鍵參數(如用戶 ID?
userid=123
、會話 ID?sessionid=abc
)進行會話保持。
?測試
(8)hdr?
原理:?HTTP 頭哈希。?使用指定的 HTTP 請求頭的值計算哈希值。需要配置頭名稱(例如?
hdr(Cookie)
,hdr(Host)
)。權重支持:?不支持。
特點:?極其靈活,可以利用任何 HTTP 頭信息做會話保持,最常用的是?
Cookie
?頭。
測試
模擬不同的瀏覽器訪問時:
瀏覽器browser1訪問,RS1接待
瀏覽器browser2訪問,就變成RS2接待了?
6、cookie
(1)概念
HAProxy 中的?cookie
?指令是實現?會話保持(Session Persistence)或粘性會話(Sticky Session)?最常用、最強大且推薦的方式之一。它通過在客戶端的瀏覽器中設置或利用一個特定的 Cookie,確保來自同一用戶的后續請求能被 HAProxy 正確地路由到最初處理其請求的同一臺后端服務器。
目的:?解決有狀態應用(Stateful Application)的問題。例如,用戶的購物車數據、登錄會話信息等通常存儲在特定后端服務器的內存或本地緩存中。如果用戶的后續請求被負載均衡到不同的服務器,這些狀態信息將丟失,導致應用出錯。
原理:
HAProxy 在將第一個響應返回給客戶端時(或者在某些模式下處理第一個請求時),會插入(Insert)?或改寫(Rewrite)?一個特殊的 HTTP?
Set-Cookie
?響應頭。這個 Cookie 的值通常直接包含或間接映射到處理該請求的后端服務器的標識符(通常是?
server
?塊中定義的?cookie
?值或內部 ID)。客戶端瀏覽器收到這個 Cookie 后會存儲它,并在后續向同一域名發送請求時,自動在?
Cookie
?請求頭中攜帶它。HAProxy 接收到后續請求時,會解析該 Cookie 的值,提取出服務器標識符,并直接將請求轉發到對應的服務器,繞過負載均衡算法。
(2)實驗舉例?
測試
-b 指定cookie值
可以看到訪問cookie值為servera時,被調度到RS1處理;?cookie值為serverb時,被調度到RS2處理
與我們在haproxy配置文件里配置的一致
7、HAProxy狀態頁
HAProxy 的狀態頁(Stats Page)?是實時監控負載均衡集群的核心工具,通過 Web 頁面展示關鍵性能指標和后端節點狀態。
(1)各種參數解析
基礎配置項解析
參數 | 說明 | 示例 |
---|---|---|
stats enable | 啟用狀態頁(無此選項則不生效) | stats enable |
stats uri | 狀態頁訪問路徑 | stats uri /admin?stats |
stats auth | 基礎認證(明文用戶/密碼) | stats auth admin:SecurePass123 |
stats refresh | 頁面自動刷新間隔(秒) | stats refresh 5s |
stats bind | 監聽地址和端口(默認同 frontend) | stats bind :1936 |
進階安全控制?
參數 | 說明 | 生產環境示例 |
---|---|---|
stats hide-version | 隱藏 HAProxy 版本號(防漏洞掃描) | stats hide-version |
stats admin | 動態啟用管理功能(條件觸發) | stats admin if { src 10.0.0.0/24 } |
stats http-request | 集成 ACL 復雜控制 | stats http-request allow if { src -f /etc/haproxy/allowlist } |
stats realm | 認證對話框提示文本 | stats realm "HAProxy Protected" |
(2)實驗
解釋:
- listen haproxystatus ——?定義名為 "haproxystatus" 的監聽塊
- mode ? ?http —— 使用 HTTP 模式(七層代理)
- bind ? ?*:9999 —— 綁定所有網絡接口的 9999 端口
- stats ? enable —— 啟用狀態統計頁面
- log ? ? global —— 使用全局日志配置
- stats ? uri /status —— 設置狀態頁的訪問路徑為 /status
- stats ? auth lincoln:lincoln —— 設置訪問認證的用戶名/密碼
重啟服務時如果報錯:
可能是SELinux的原因,把其關閉:
?
再試一次應該就沒報錯了
測試
瀏覽器訪問剛剛寫的端口號9999,后面加/status
http://172.25.254.100:9999/status
出現輸入用戶名和密碼,輸入剛剛設定的,這里我設定的是自己的名字:?
登錄成功后,訪問到頁面:
8、IP透傳
HAProxy 的?IP 透傳?是指將原始客戶端的真實 IP 地址傳遞給后端服務器,而不是讓后端服務器只看到 HAProxy 自身的 IP 地址。這對于后端應用至關重要,因為它需要知道真實的客戶端信息來進行日志記錄、訪問控制、地理定位、速率限制、安全審計等操作。
HAProxy 本身作為反向代理或負載均衡器,是客戶端與后端服務器之間的中間節點。默認情況下,后端服務器看到的 TCP 連接源 IP 地址就是 HAProxy 的 IP 地址。
(1)7層ip透傳
當haproxy工作在七層的時候,也可以透傳客戶端真實IP至后端服務器
進入haproxy配置文件

開啟Listen就把frontend和backend關了
(2)4層ip透傳
1)未開啟時
未開啟4層ip透傳時的各種配置:
haproxy.cfg
nginx.conf(兩臺RS)
未開啟4層ip透傳時的訪問測試極其日志:
訪問測試
日志查看
在一臺RS上查看nginx日志會發現,其真實訪問源地址是看不到的(紅框為-)
2)開啟時?
?開啟4層ip透傳時的各種配置:
nginx.conf(兩臺RS)
haproxy.cfg
?開啟4層ip透傳時的訪問測試極其日志:
訪問測試
查看日志nginx
這樣就看到源ip地址了
9、ACL
HAProxy 的 ACL 是其核心功能之一,用于定義復雜的流量匹配規則,實現基于請求內容(如 URL、Header、IP、路徑等)的智能路由、過濾或決策。
(1)Client里做解析
先在Client里做域名解析,不然后續測試訪問不了
解析在/etc/hosts做
這樣就有解析了
(2)基本配置
開啟frontend、backend
其余的Listen引掉
(3)ACL配置選項
1)基本語法
acl <acl_name> <匹配條件類型> <匹配參數> [標志]
解釋:
- acl名稱(ACL-Name)? ? ? ? ? ? ? ?——?可以使用大字母A-Z、小寫字母a-z、數字0-9、冒號:、點.、中橫線和下劃線,并且嚴格區分大小寫
- 匹配條件類型(ACL-criterion)—— 下面另外列表解釋
- 匹配參數 ????????????????????????????????????——?匹配的具體值(如?
/api
,?User-Agent
,?192.168.1.0/24
)- 標志? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????——?可選修飾符(如?
-i
?忽略大小寫,-m
?匹配模式)
2)常用匹配條件類型(ACL-criterion)詳解:
路徑匹配 (URL Path)
條件類型 | 說明 | 示例 |
---|---|---|
path | 精確匹配路徑 | acl exact_path path /login |
path_beg | 路徑開頭匹配 | acl is_api path_beg /api |
path_end | 路徑結尾匹配 | acl is_jpg path_end .jpg |
path_sub | 路徑包含子串 | acl has_id path_sub /user/ |
path_dir | 包含目錄匹配 | acl in_images path_dir /images/ |
path_reg | 正則表達式匹配 | acl uuid_path path_reg ^/user/[0-9a-f]{8}- |
path_len | 路徑長度比較 | acl long_path path_len gt 100 |
域名/主機頭匹配 (Host)
條件類型 | 說明 | 示例 |
---|---|---|
hdr(host) | 精確匹配 Host 頭 | acl main_site hdr(host) www.example.com |
hdr_reg(host) | 正則匹配 Host | acl subsite hdr_reg(host) ^app..example.com$ |
dom | 同 hdr(host) (舊式寫法) | acl legacy dom legacy.example.com |
IP地址匹配
條件類型 | 說明 | 示例 |
---|---|---|
src | 源IP匹配 | acl lan src 192.168.1.0/24 |
src_port | 源端口匹配 | acl high_port src_port gt 1024 |
dst | 目標IP匹配 | acl vip dst 10.0.0.100 |
dst_port | 目標端口匹配 | acl https_port dst_port 443 |
HTTP頭部匹配
語法 | 說明 | 示例 |
---|---|---|
hdr(<name>) | 檢查頭部存在/值 | acl has_token hdr(X-Auth-Token) -m found |
hdr_reg(<name>) | 正則匹配頭部值 | acl is_bot hdr_reg(User-Agent) (bot|crawl) |
hdr_sub(<name>) | 頭部包含子串 | acl is_curl hdr_sub(User-Agent) curl |
hdr_beg(<name>) | 頭部開頭匹配 | acl is_moz hdr_beg(User-Agent) Mozilla |
hdr_cnt(<name>) | 頭部數量檢查 | acl many_cookies hdr_cnt(Cookie) gt 5 |
HTTP方法/版本
條件類型 | 說明 | 示例 |
---|---|---|
method | HTTP方法匹配 | acl is_post method POST |
method_len | 方法長度比較 | acl long_method method_len gt 5 |
ver | HTTP版本 | acl http2 ver 2 |
3)標志項詳解
標志 | 說明 | 示例 |
---|---|---|
-i | 忽略大小寫 | hdr(host) -i EXAMPLE.COM |
-m | 匹配模式 | -m str :字符串匹配-m beg :開頭匹配-m end :結尾匹配-m sub :子串匹配-m reg :正則匹配-m found :存在即匹配 |
-f | 從文件加載 | src -f /path/to/ip.list |
-n | 數值比較 | path_len -n gt 100 |
(4)ACL配置選項的實驗(舉一個例子)
1)添加基礎acl規則和hdr_dom(host)
解釋:
- hdr_dom(host)?—— 精確匹配 Host 頭
- -i —— 忽略大小寫
- www.lincoln.org ——?hdr_dom(host)所匹配的域名
- if test —— 條件語句,即匹配test這個acl規則
測試
可以看到,設置了acl規則后,我們訪問www.lincoln.org就會到RS1主機,這就是acl規則
(5)實驗——域名匹配
進入haproxy的配置文件
測試結果:
[root@Client ~]# curl www.lincoln.org
RS1 - 172.25.254.10
[root@Client ~]# curl www.lincoln.org
RS2 - 172.25.254.20
10、自定義錯誤頁面
(1)概念
在 HAProxy 中,自定義報錯頁面是一項關鍵功能,它允許你替換 HAProxy 生成的默認錯誤響應(通常是簡短、技術性的純文本或 JSON),為用戶或客戶端提供更友好、更專業、更具品牌特色或包含更多指導信息的 HTML 錯誤頁面。
(2)實驗
寫了Listen的話frontend和backend就要記得關閉!
建立自定義報錯文件
?
測試
關閉兩個RS的nginx,模擬服務斷開
然后瀏覽器訪問ip,就能看到自定義報錯界面了
11、HAProxy 四層負載
HAProxy 是一個高性能、高可用性的負載均衡器和反向代理軟件。它的四層負載均衡模式,通常稱為?TCP 模式或?Layer 4 (L4) 模式,專注于在傳輸層(TCP)?工作。這意味著 HAProxy 在此模式下不解析應用層協議(如 HTTP)的內容,它只處理 TCP 連接本身。
(1)實驗——對 MySQL 服務實現四層負載
?
兩臺RS安裝mariadb-server
Client安裝mariadb(注意不是mariadb-server)
測試
12、證書
(1)證書制作
所有主機都關閉SELinux(命令setenforce 0)
解釋:
openssl req
這是 OpenSSL 的子命令,用于處理證書簽名請求。雖然名字叫?
req
,但結合?-x509
?選項時,它可以直接生成自簽名證書,而無需先生成 CSR。
-newkey rsa:2048
-newkey
:指示 OpenSSL 生成一個新的私鑰。
rsa:2048
:指定新私鑰的算法為?RSA,密鑰長度為?2048 位。這是目前廣泛使用的安全標準。
-nodes
這個選項的意思是?"不要用密碼加密私鑰"。
如果省略?
-nodes
,OpenSSL 會在生成私鑰時提示你設置一個密碼。每次 HAProxy(或其他服務)啟動使用這個私鑰時,都需要輸入密碼,這對于自動啟動的服務非常不便。重要提示:?使用?
-nodes
?意味著私鑰文件 (lincoln.org.key
) 是未加密存儲在磁盤上的。必須嚴格限制該文件的訪問權限(通常設置為?600
?或?400
,僅限 root 或特定服務用戶讀取),否則存在安全風險。
-sha256
指定生成證書請求(以及最終證書)時使用的哈希算法為?SHA-256。
這是當前推薦的安全哈希算法,替代了較弱的 SHA-1 或 MD5。
-keyout /etc/haproxy/certs/
lincoln
.org.key
-keyout
:指定新生成的私鑰應保存到的文件路徑和名稱。這里私鑰將被保存到?
/etc/haproxy/certs/lincoln.org.key
。確保?/etc/haproxy/certs/
?目錄存在,或者你有權限創建它。
-x509
這是命令的核心選項,改變了?
openssl req
?的默認行為。通常?
req
?用于生成證書簽名請求,需要提交給證書頒發機構 (CA) 簽名。
-x509
?選項告訴 OpenSSL?直接生成一個自簽名的 X.509 證書,而不是生成 CSR。該證書將使用剛剛生成的私鑰進行簽名。
-days 365
指定生成的自簽名證書的有效期,單位為天。
這里設置為?365 天(1 年)。你可以根據需要調整這個值(例如?
-days 730
?表示 2 年)。
-out /etc/haproxy/certs/
lincoln
.org.crt
-out
:指定生成的自簽名證書應保存到的文件路徑和名稱。這里證書將被保存到?
/etc/haproxy/certs/lincoln.org.crt
。
按照提示來輸入名字那些
之后將key和crt一起放到.pem里
這樣證書就生成完畢了
進haproxy配置文件配置?
(2)測試訪問
結束