一、負載均衡
負載均衡是網絡架構和分布式系統中至關重要的技術,其核心作用是將大量的并發請求或數據流量合理分配到多個服務器(或其他資源節點)上,從而解決單節點壓力過大、資源利用率低、系統穩定性差等問題。
作用
1. 提高系統吞吐量和并發處理能力
負載均衡通過將請求分散到多臺服務器,讓每臺服務器處理的請求量控制在合理范圍內,整體提升系統的并發處理能力
2. 避免單點故障,增強系統可用性
負載均衡會實時監測后端服務器的健康狀態(如通過心跳檢測、請求響應時間等),當某臺服務器故障時,自動將請求轉發到其他正常服務器,確保服務不中斷,顯著提高系統的可用性。
3. 優化資源利用率,降低成本
負載均衡通過合理分配請求,讓所有服務器的資源(CPU、內存等)得到均衡利用,避免資源閑置,從而在滿足業務需求的前提下,減少不必要的服務器投入成本。
4. 提升用戶體驗(降低響應延遲)
負載均衡將請求分配給負載較輕的服務器,保證每臺服務器都能快速處理請求,降低整體響應延遲,提升用戶體驗。
5. 支持業務擴展(彈性伸縮)
當業務增長(如電商大促、直播峰值)時,只需通過負載均衡新增服務器節點,即可無縫擴展系統處理能力,無需修改核心架構。
反之,業務低谷時可減少服務器節點,通過負載均衡自動調整流量分配,實現資源的彈性伸縮。
6. 增強安全性(輔助防護)
過濾惡意請求(如 DDoS 攻擊的流量清洗);
隱藏后端服務器的真實 IP 地址,減少直接暴露在公網的風險;
支持 SSL/TLS 加密,處理 HTTPS 請求的解密 / 加密工作,減輕后端服務器負擔。
四層負載均衡
原理
四層負載均衡工作在傳輸層,其轉發邏輯依賴于數據包的源 IP、目標 IP、源端口、目標端口以及協議類型(TCP/UDP) 等信息。
- 當客戶端請求到達負載均衡器時,負載均衡器會分析數據包的上述四層信息,根據預設策略(如輪詢、源 IP 哈希等)選擇后端服務器;
- 隨后,負載均衡器會修改數據包的目標 IP 和端口(替換為選中的后端服務器 IP 和端口),并將數據包轉發給該服務器;
- 服務器處理完成后,響應數據包會原路返回負載均衡器,再由負載均衡器修改源 IP 和端口(替換為自身的 IP 和端口),最終返回給客戶端。
整個過程中,負載均衡器不會解析數據包的具體內容(如 HTTP 請求的 URL、參數等),僅基于傳輸層信息進行轉發,因此速度更快、開銷更低。
支持軟件
- vs:重量級四層負載均衡器。
- Nginx:輕量級四層負載均衡器,可緩存。(nginx四層是通過upstream模塊)
- Haproxy:模擬四層轉發。
七層負載均衡
原理
七層負載均衡工作在應用層,其轉發邏輯依賴于對請求內容的深度解析:
- 當客戶端請求到達負載均衡器時,負載均衡器會先 “拆開” 數據包,解析應用層協議的具體內容(例如,HTTP 請求的
/api/user
路徑、Host
頭、Cookie
信息等); - 根據預設的應用層策略(如 “URL 路徑匹配”“請求頭關鍵字”“用戶身份” 等),選擇最合適的后端服務器;
- 將請求轉發到選中的服務器,同時可能對請求內容進行修改(如添加 / 刪除請求頭、重寫 URL);
- 服務器響應后,負載均衡器再將響應返回給客戶端,過程中也可對響應內容進行處理(如壓縮、添加響應頭)。
支持軟件
- Nginx:基于http協議(nginx七層是通過proxy_pass)
- Haproxy:七層代理,會話保持、標記、路徑轉移等。
四層和七層區別
維度 | 四層負載均衡 | 七層負載均衡 |
---|---|---|
工作層級 | 傳輸層(TCP/UDP) | 應用層(如 HTTP、HTTPS) |
轉發依據 | IP、端口、協議 | URL、HTTP 頭部、Cookie 等應用層信息 |
性能 | 高(無需解析應用數據) | 較低(需解析應用層內容) |
靈活性 | 較低(策略基于網絡層信息) | 較高(可根據應用邏輯定制策略) |
會話保持 | 依賴源 IP 哈希等簡單方式 | 支持基于 Cookie、Session 的精準保持 |
典型應用 | 數據庫連接、視頻流、UDP 服務 | Web 服務器、API 網關、HTTPS 請求調度 |
二、haproxy簡介
HAProxy(High Availability Proxy)是一款由法國人Willy Tarreau開發的高性能、開源的TCP和HTTP負載均衡器。它使用C語言編寫,具備高并發處理能力和豐富的功能特性,廣泛應用于各種需要高負載和高可用性的Web站點和應用程序中。
開發者:Willy Tarreau
類型:高性能的TCP和HTTP負載均衡器
特點:免費、快速、可靠
主要功能:負載均衡、健康檢查、會話保持、SSL/TLS支持、HTTP重寫、壓縮等
三、haproxy安裝
安裝
dnf install haproxy -y
版本查看
[root@haproxy ~]# haproxy -v
HAProxy version 2.4.22-f8e3218 2023/02/14 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 5.14.0-427.13.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 10 10:29:16 EDT 2024 x86_64
基本信息
軟件安裝包: 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
四、haproxy基本配置信息
1.global-全局配置
全局配置影響 HAProxy 進程的整體行為,如日志、權限、資源限制等。
log <地址> <設備>
定義全局的syslog服務器;日志服務器需要開啟UDP協議,最多可以定義兩個
chroot <路徑>
為 HAProxy 進程設置根目錄(安全加固,限制進程訪問范圍),通常為 /var/lib/haproxy。
pidfile <路徑>
指定pid文件
stats socket <路徑> [參數]
定義統計信息的 Unix 套接字路徑(用于通過 socat 管理 HAProxy)
user <用戶名> | group <組名>
指定 HAProxy 進程運行的用戶和組(非 root 賬戶,增強安全性),通常為 haproxy。
daemon
以守護進程(后臺)模式運行 HAProxy。
maxconn <數值>
全局最大并發連接數(每個進程的最大連接數)。
nbproc <數值>
啟動的進程數(默認 1,多核服務器可設置為 CPU 核心數,提高并發處理能力)
cpu-map 1 0 #指定第一個work綁定第一個cpu核心
cpu-map 2 1 #指定第二個work綁定第二個cpu核心
nbthread <數值>
指定haproxy的線程數量,默認每個進程一個線程
注意:總線程數建議不超過 CPU 核心數(或略高),避免線程切換開銷過大(例如 8 核 CPU 可設為
nbproc 2 + nbthread 4
,總線程 8)。
maxsslconn <數值>
每個haproxy進程ssl最大連接數,用于haproxy配置了證書的場景下
maxconnrate <數值>
指定每個客戶端每秒建立連接的最大數量
2.defaults -默認配置
定義前端(frontend
)和后端(backend
)的默認參數,可被后續配置繼承,減少重復設置。
mode <模式>
haproxy使用的來連接協議
負載均衡模式:http(七層,基于 HTTP 協議)或 tcp(四層,基于 TCP 協議)。
option httplog
日志記錄選項,httplog表示記錄與 HTTP會話相關的各種屬性值
包括 HTTP請求、會話狀態、連接數、源地址以及連接時間等
option dontlognull
不記錄空會話連接日志(如健康檢查的空請求,減少日志冗余)。
option http-server-close
等待客戶端完整HTTP請求的時間,此處為等待10s。
option forwardfor
僅
mode http
有效,在 HTTP 頭中添加X-Forwarded-For
字段,傳遞客戶端真實 IP 給后端服務器。
option redispatch
當server Id對應的服務器掛掉后,強制定向到其他健康的服務器,重新派發
option http-keep-alive
開啟與客戶端的會話保持
retries <次數>
連接后端服務器失敗次數
timeout connect <時間>
設置等待服務器連接成功的時間
timeout client <時間>
設置服務器超時時間,即允許服務器處于既不接收也不發送數據的非活動時間(例如 50000 表示 50 秒,或者直接寫50s)。
timeout server <時間>
設置服務器超時時間,即允許服務器處于既不接收也不發送數據的非活動時間
timeout http-keep-alive <時間>
session 會話保持超時時間,此時間段內會轉發到相同的后端服務器
timeout check <時間>
指定后端服務器健康檢查的超時時間
errorfile <狀態碼> <文件路徑>
自定義 HTTP 錯誤頁面(例如 errorfile 503 /etc/haproxy/errors/503.http 表示 503 錯誤時返回指定頁面)。
3.frontend-前端配置
定義監聽的端口、協議及請求轉發規則(接收客戶端請求的入口)。
bind <地址:端口>
監聽的 IP 地址和端口(*:80 表示監聽所有 IP 的 80 端口;192.168.1.1:443 表示指定 IP 的 443 端口)。
mode <模式>
同 defaults,可覆蓋默認模式(例如前端同時處理 HTTP 和 TCP 時需單獨指定)。
acl <名稱> <條件>
定義訪問控制列表(ACL)
use_backend <后端名稱> if <acl名稱>
當 ACL 條件滿足時,將請求轉發到指定后端(例如 use_backend static_servers if url_static)。
default_backend <后端名稱>
當所有 ACL 條件不匹配時,默認轉發的后端。
4.default-后端配置
定義負載均衡的后端服務器集群及轉發規則(處理前端轉發的請求)。
mode <模式>
需與前端對應(http 或 tcp),否則可能導致協議不兼容。
balance <算法> 負載均衡算法(核心參數):
設置負載均衡算法(核心參數),默認roundrobin
server <名稱> < IP:端口> [參數]
定義后端服務器
參數:
- check:啟用健康檢查;
- inter <時間>:健康檢查間隔(例如 inter 2000 表示 2 秒)
- rise <次數>:連續健康檢查成功 <次數> 后,服務器從下線狀態恢復(默認2)
- fall <次數>:連續健康檢查失敗 <次數> 后,服務器標記為下線(默認3)
- weight <權重>:服務器權重(默認為1,最大值為256,0表示不參與負載均衡,但仍接受持久連接)
- backup:標記為備用服務器(僅當主服務器全部下線時啟用),例如sorry server
- disabled :將后端服務器標記為不可用狀態,即維護狀態
redirect <規則>
將請求臨時(302)重定向至其它URL,只適用于http模式
frontend+default示例配置
frontend webcluster_80 bind *:80 #監聽服務器上所有網絡接口(*)的 80 端口,即接收來自任意 IP 的 HTTP 請求。mode http #工作在七層(應用層)HTTP 模式,支持解析 HTTP 協議內容use_backend webserver #無條件將所有接收到的請求轉發到名為 webserver 的后端服務器集群
backend webserverbalance roundrobin #算法:輪詢server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
#定義后端服務器 web1:
#192.168.60.10:80 服務器的 IP 和端口;
#check:啟用健康檢查(定期檢測服務器是否可用);
#inter 3s:健康檢查間隔為 3 秒;
#fall 3:連續 3 次檢查失敗,標記服務器為 “下線”(不再分配請求);
#rise 2:連續 2 次檢查成功,標記服務器為 “上線”(恢復分配請求);
# weight 2:權重為 2(權重越高,分配的請求比例越大,默認權重為 1)。server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup
#定義 備用服務器 error:
#192.168.60.30:8080:備用服務器的 IP 和端口(端口為 8080,與主服務器不同);
#backup:標記為備用機,僅當所有主服務器(web1、web2)都下線時才啟用(用于故障兜底,如返回維護頁面)。
listen簡化配置
使用listen替換 frontend和backend的配置方式,可以簡化設置,通常只用于TCP協議的應用
#下方配置與上方示例配置實現效果完全相同
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup
五、熱更新工具(socat)
socat
是一款功能強大的網絡工具,全稱為 Socket Cat,主要用于在兩個數據流向之間建立連接并轉發數據。它支持多種協議和數據類型,靈活度極高,常用于網絡調試、端口轉發、數據轉換等場景。
socat
的核心是在 兩個地址(address) 之間建立雙向通信,實現數據的實時轉發。這兩個地址可以是:
- 網絡端口(TCP/UDP)
- 文件
- 管道(pipe)
- 設備(如串口
/dev/ttyUSB0
) - 標準輸入輸出(
stdin/stdout
) - 進程(通過命令執行)
可以將socat和haproxy相結合以實現haproxy服務的熱更新等復雜功能,使用socat修改haproxy配置,無需重啟即可使配置生效
1.安裝
dnf install socat-1.7.4.1-5.el9.x86_64 -y
2.haproxy
vim /etc/haproxy/haproxy.cfg
#寫入
stats socket /var/lib/haproxy/stats mode 600 level admin
#stats socket:聲明一個統計套接字,用于進程間通信(IPC)。
#/var/lib/haproxy/stats:套接字文件的路徑,HAProxy 會在啟動時創建此文件。
#mode 600:設置套接字文件的權限為 rw-------,即只有文件所有者可以讀寫,增強安全性。
#level admin:授予最高權限(admin 級別),允許執行所有管理命令。
3…查看haproxy幫助
可以看到詳細操作方法
echo "help" | socat stdio /var/lib/haproxy/stats
4.查看haproxy狀態
echo "show info" | socat stdio /var/lib/haproxy/stats
5.查看集群狀態
echo "show servers state" | socat stdio /var/lib/haproxy/stats# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
3 webcluster_80 1 web1 192.168.60.10 2 0 2 2 770 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 770 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 770 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
...
字段名 | 含義 |
---|---|
be_id | 后端(Backend)的唯一數字標識符 |
be_name | 后端的名稱 |
srv_id | 服務器在后端中的唯一數字標識符 |
srv_name | 服務器的名稱 |
srv_addr | 服務器的 IP 地址或主機名 |
srv_op_state | 服務器的運行狀態(數字編碼) |
srv_admin_state | 服務器的管理狀態 |
srv_uweight | 用戶配置的服務器權重 |
srv_iweight | 服務器的初始權重(基于健康檢查動態調整前的權重) |
srv_time_since_last_change | 自上次狀態變更以來的時間(毫秒) |
srv_check_status | 最近一次健康檢查的狀態 |
srv_check_result | 健康檢查的詳細結果 |
srv_check_health | 健康狀態(成功 / 失敗次數) |
srv_check_state | 健康檢查的當前階段 |
srv_agent_state | 代理檢查狀態(如果啟用了 agent 檢查) |
bk_f_forced_id | 后端強制狀態的 ID(用于故障轉移) |
srv_f_forced_id | 服務器強制狀態的 ID |
srv_fqdn | 服務器的完全限定域名 |
srv_port | 服務器端口號 |
srvrecord | 服務器記錄(內部使用) |
srv_use_ssl | 是否使用 SSL 連接到服務器 |
srv_check_port | 健康檢查使用的端口 |
srv_check_addr | 健康檢查使用的 IP 地址 |
srv_agent_addr | 代理檢查的地址 |
srv_agent_port | 代理檢查的端口 |
6.查看集群權重
echo "get weight webcluster_80/web1" | socat stdio /var/lib/haproxy/stats
2 (initial 2)echo "get weight webcluster_80/web2" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
7.設置集群服務權重
#設置web1權重為1
echo "set weight webcluster_80/web1 1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "get weight webcluster_80/web1" | socat stdio /var/lib/haproxy/stats
1 (initial 2)#權重為1(之前是2)
8.下線后端服務器
echo "disable server webserver_80/web1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "show servers state" | socat stdio /var/lib/haproxy/stats
... #srv_op_state=0 (DOWN)服務器已宕機,不接收流量
3 webcluster_80 1 web1 192.168.60.10 0 1 1 2 14 6 3 0 14 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 1909 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 1909 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
...srv_op_state 服務器運行狀態
0 DOWN 服務器已宕機,不接收流量(健康檢查失敗或手動禁用)。
1 UP 服務器正常運行,但權重為 0(不參與負載均衡)。
2 UP 服務器正常運行,可接收流量(默認狀態)。
3 MAINT 服務器處于維護模式(手動禁用),不接收新流量,但保留現有連接。
4 MAINT(via) 服務器通過上層對象(如后端)繼承維護模式。
5 UP (q) 服務器正常,但處于排隊狀態(等待連接數下降到閾值以下)。
6 DRAIN 服務器處于排水模式(只處理現有連接,不接收新連接)。
7 UP (fv) 服務器正常,但因前端故障(如 SSL 錯誤)暫時不可用。
8 MAINT (fv) 服務器因前端故障處于維護模式。
9 UP (bck) 服務器正常,但僅作為備份服務器(主服務器全部不可用時啟用)。
10 MAINT (bck) 備份服務器處于維護模式。
11 UP (chk) 服務器正常,但正在進行初始健康檢查(尚未確認狀態)。
12 MAINT (chk) 服務器在維護模式下進行健康檢查。
13 UP (nolb) 服務器正常,但被標記為不參與負載均衡(nolb 選項)。
14 MAINT (nolb) 不參與負載均衡的服務器處于維護模式。
9.上線后端服務器
echo "enable server webcluster_80/web1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "show servers state" | socat stdio /var/lib/haproxy/stats#srv_op_state=2 (UP)服務器正常運行,可接收流量量
3 webcluster_80 1 web1 192.168.60.10 2 0 1 2 200 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 2300 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 2300 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
六、haproxy狀態頁
1.配置
vim /etc/haproxy/haproxy.cfg
#寫入
listen stats:mode httpbind *:9999log global #使用全局日志stats uri /stats #狀態頁面的訪問路徑為 http://IP:9999/statsstats refresh 1s #自動刷新間隔1sstats auth dll:dll #認證 賬號:dll 密碼:dll
2.訪問
3.信息
類別 | 子項 | 說明 |
---|---|---|
session rate(每秒的連接會話信息) | cur | 每秒的當前會話數量 |
max | 每秒新的最大會話數量 | |
limit | 每秒新的會話限制量 | |
sessions(會話信息) | cur | 當前會話量 |
max | 最大會話量 | |
limit | 限制會話量 | |
Total | 總共會話量 | |
LBTot | 選中一臺服務器所用的總時間 | |
Last | 和服務器的持續連接時間 | |
Bytes(流量統計) | In | 網絡的字節輸入總量 |
Out | 網絡的字節輸出總量 | |
Denied(拒絕統計信息) | Req | 拒絕請求量 |
Resp | 拒絕回復量 | |
Errors(錯誤統計信息) | Req | 錯誤請求量 |
conn | 錯誤鏈接量 | |
Resp | 錯誤響應量 | |
Warnings(警告統計信息) | Retr | 重新嘗試次數 |
Redis | 再次發送次數 | |
Server (real server 信息) | Status | 后端機的狀態,包括 UP 和 DOWN |
LastChk | 持續檢查后端服務器的時間 | |
Wght | 權重 | |
Act | 活動鏈接數量 | |
Bck | 備份的服務器數量 | |
Chk | 心跳檢測時間 | |
Dwn | 后端服務器連接后都是 DOWN 的數量 | |
Dwntme | 總的 downtime 時間 | |
Thrtle | server 狀態 |
七、haproxy算法
靜態算法
靜態算法:按照事先定義好的規則輪詢公平調度,不關心后端服務器的當前負載、連接數和響應速度等,且無法實時修改權重(只能為0和1,不支持其它值),只能靠重啟HAProxy生效。
static-rr
按順序循環分發請求,不考慮服務器實時負載
- 不支持運行時利用socat進行權重的動態調整(只支持0和1,不支持其它值)
- 不支持端服務器慢啟動
- 其后端主機數量沒有限制,相當于LVS中的 wrr
慢啟動是指在服務器剛剛啟動上不會把他所應該承擔的訪問壓力全部給它,而是先給一部分,當沒
問題后在給一部分
實例配置
listen webcluster_80bind *:80mode httpbalance static-rrserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup[root@ceshi ~]# for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
first
根據服務器在列表中的位置,自上而下進行調度,當第一臺服務器的連接數達到上限,新請求才會分配給下一臺服務
- 其會忽略服務器的權重設置
- 不支持用socat進行動態修改權重,可以設置0和1,可以設置其它值但無效
#僅修改算法
...balance first
...
#訪問效果
while true;do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs11-192.168.60.10
rs11-192.168.60.10
...
#連續訪問,但是rs1跑不滿,所以一直訪問rs1
動態算法
roundroubin
默認調度算法,使用極為廣泛,基于權重動態輪詢
- 支持權重的運行時調整,不同于lvs中的rr輪訓模式
- HAProxy中的roundrobin支持慢啟動
- 其每個后端backend中最多支持4095個real server
- 支持對real server權重動態調整
#僅修改算法為roundroubin
...balance roundrobin
...
for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
leastconn
當前后端服務器加權連接最少的優先調度。
優先選擇當前連接數最少且可用的服務器,權重僅在連接數相同的服務器中生效。
- 比較適合長連接的場景使用,比如:MySQL等場景。
- 支持動態調整權重
- 支持慢啟動
...balance leastconn
...
#連接數最少的優先訪問
for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
其他算法
其它算法即可作為靜態算法,也可以通過選項成為動態算法
source
源地址hash,基于?戶源地址hash并將請求轉發到后端服務器。后續同一個源地址請求將被轉發至同一個后端web服務器。
適用于需要會話保持,但又不支持cookie和緩存的場景
缺點:
map-base取模法
默認,取模法,對source地址進行hash計算,再基于服務器總權重的取模,最終結果決定將此請
求轉發至對應的后端服務器。
基于權重取模,hash(source_ip)%所有后端服務器相加的總權重
- 靜態方法,不支持socat調整、慢啟動
- 當服務器總權重變化時(服務器宕機、開啟),會導致調度結果整體變化
例如,后端有三臺服務器,每臺服務器權重都為1,則總權重為3,haproxy給源地址做hash計算,hash_value%3。其中獲取的值如果為0,發給第一臺服務器;如果為1,發給第二臺服務器;如果為2,發給第三臺服務器。如果一臺服務器壞掉了,其要在通過hash_value%3計算,因權重發?變化?導致調度結果整體改變。
配置
listen webcluster_80bind *:80mode httpbalance sourceserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
#測試 同ip訪問調度至同一后端服務器
[root@ceshi ~]# for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
...
[root@test1 ~]# for n in {1..10};do curl 192.168.60.30;done
rs22-192.168.60.20
rs22-192.168.60.20
...
一致性hash
-
一致性哈希,當服務器的總權重發生變化時,對調度結果影響是局部的,不會引起大的變動
-
支持慢啟動,socat熱更新
算法解釋
1、后端服務器哈希環點keyA=hash(后端服務器虛擬ip)%(2^32)
2、客戶機哈希環點key1=hash(client_ip)%(2^32) 得到的值在[0—4294967295]之間,
3、將keyA和key1都放在hash環上,將用戶請求調度到離key1最近的keyA對應的后端服務器
如圖左
將三臺服務器ip通過運算得到Key A、Key B、Key C,放到對應位置,客戶端ip同理進行運算,放到對應位置
讓每個客戶端調度至距離最近的服務器,得到
object1—A
object2—B
object3—C
object4—C
注意這里看起來好像是object1距離C更近,但是object1還是調度至A上,為什么——哈希環是一條的單行道,只能順時針選擇最近的單位,禁止逆行。object2、object4同理如圖右
當服務器B宕機后,原本調度至B的object4順時針選擇,調度至C上
一致性hash算法可以保證當后端環境變化時,影響最小,某臺服務器宕機只會影響本臺服務器客戶,不像map-base,某臺服務器宕機后會導致服務器總權重變化,調度結果整體變化
配置
listen webcluster_80bind *:80mode httpbalance sourcehash-type consistent server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
uri
根據用戶請求的 URI 左半部分或整體進行哈希計算,確保相同 URI 的請求被發送到同一臺后端服務器。
適用于后端是緩存服務器場景。
默認是靜態算法,也可以通過hash-type指定map-based和consistent,來定義使用取模法還是一致性
hash
此算法基于應用層,所以只支持 mode http ,不支持 mode tcp
取模法
listen webcluster_80bind *:80mode httpbalance uriserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance urihash-type consistentserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backuprs1寫入文件
[root@rs11 /]# echo rs1 index1 > /usr/share/nginx/html/index1.html
[root@rs11 /]# echo rs1 index2 > /usr/share/nginx/html/index2.html
[root@rs11 /]# echo rs1 index3 > /usr/share/nginx/html/index3.html[root@rs22 ~]# echo rs2 index1 > /usr/share/nginx/html/index1.html
[root@rs22 ~]# echo rs2 index2 > /usr/share/nginx/html/index2.html
[root@rs22 ~]# echo rs2 index3 > /usr/share/nginx/html/index3.html測試
[root@ceshi ~]# curl 192.168.60.30/index1.html
rs1 index1
[root@ceshi ~]# curl 192.168.60.30/index2.html
rs1 index2
[root@ceshi ~]# curl 192.168.60.30/index3.html
rs1 index3#使用本地ip測試
[C:\~]$ curl 192.168.60.30/index1.html% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 11 100 11 0 0 697 0 --:--:-- --:--:-- --:--:-- 733
rs2 index1
[C:\~]$ curl 192.168.60.30/index2.html
...
rs2 index2
[C:\~]$ curl 192.168.60.30/index3.html
...
rs2 index3
url_param
對用戶請求的url中的 params 部分中的一個參數key對應的value值作hash計算,并由服務器總權重相除以后派發至某挑出的服務器,后端搜索同一個數據會被調度到同一個服務器
通常用于追蹤用戶,以確保來自同一個用戶的請求始終發往同一個real server
如果無沒key,將按roundrobin算法
取模法
listen webcluster_80bind *:80mode httpbalance url_param nameserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 check server error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance url_param namehash-type consistentserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
#測試 參數一致調度至同一個服務器
[root@ceshi ~]# curl 192.168.60.30/index.html?name=6hj3
rs11-192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/index.html?name=123
rs22-192.168.60.20
[root@ceshi ~]# curl 192.168.60.30/index.html?name=*90k
rs11-192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/index.html?name=6hj3
rs11-192.168.60.10
hdr
根據 HTTP 請求頭進行哈希計算,確保具有相同請求頭的請求被發送到同一臺后端服務器。此處由name指定的http首部會被取出并作hash計算。
然后由服務器總權重取模以后派發至某挑出的服務器,如果無有效值,則會使用默認的輪詢調度。
取模法
listen webcluster_80bind *:80mode httpbalance hdr(User-Agent)server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance hdr(User-Agent) #根據瀏覽器型號hash-type consistentserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup#測試
curl -v 192.168.60.30
* Trying 192.168.60.30:80...
* Connected to 192.168.60.30 (192.168.60.30) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.60.30
> User-Agent: curl/7.76.1 #這次訪問方式為curl
> Accept: */*
...
rs22-192.168.60.20
#使用edge測試
[root@ceshi ~]# curl -vA edge 192.168.60.30
rs22-192.168.60.20
#火狐
[root@ceshi ~]# curl -A firefox 192.168.60.30
rs11-192.168.60.10
#谷歌
[root@ceshi ~]# curl -A Google 192.168.60.30
rs22-192.168.60.20
#使用相同的瀏覽器會調度至相同服務器
[root@ceshi ~]# curl -A Google 192.168.60.30
rs22-192.168.60.20
[root@ceshi ~]# curl -A firefox 192.168.60.30
rs11-192.168.60.10
八、基于cookie的會話保持
為當前server指定cookie值,實現基于cookie的會話黏性,相對于基于 source 地址hash調度算法對客戶端的粒度更精準,但同時也加大了haproxy負載,目前此模式使用較少, 已經被session共享服務器代替
不支持 tcp mode
配置
listen webcluster_80bind *:80mode httpbalance roundrobincookie WEBCOOKIE insert nocache indirect
##name: cookie 的 key名稱,用于實現持久連接
#insert: 插入新的cookie,默認不插入cookie
#indirect: 如果客戶端已經有cookie,則不會再發送cookie信息
#nocache: 當client和hapoxy之間有緩存服務器(如:CDN)時,不允許中間緩存器緩存cookie,因為這會導致很多經過同一個CDN的請求都發送到同一臺后端服務器server web1 192.168.60.10:80 check cookie web1 #指定cookie為web1server web2 192.168.60.20:80 check cookie web2server error 192.168.60.30:8080 backup
瀏覽器中F12查看詳細信息
測試
#指定cookie訪問
[root@ceshi ~]# curl -b WEBCOOKIE=web1 192.168.60.30
rs11-192.168.60.10
[root@ceshi ~]# curl -b WEBCOOKIE=web1 192.168.60.30
rs11-192.168.60.10
[root@ceshi ~]# curl -b WEBCOOKIE=web2 192.168.60.30
rs22-192.168.60.20
九、IP透傳
四層
haproxy
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check send-proxyserver web2 192.168.60.20:80 check send-proxyserver error 192.168.60.30:8080 backup
nginx
http {log_format main '$remote_addr - $remote_user [$time_local] "$request" '' "$proxy_protocol_addr"'#記錄透傳過來的ip'$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
...server {listen 80 proxy_protocol; ##啟用此項,將無法直接訪問此網站,只能通過四層代理訪問listen [::]:80;server_name _;root /usr/share/nginx/html;
查看日志
[root@rs11 html]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:20:47:19 +0800] "GET / HTTP/1.1" "192.168.60.66"200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:20:47:27 +0800] "GET / HTTP/1.1" "192.168.60.66"200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:20:47:50 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
192.168.60.30 - - [23/Jul/2025:20:47:52 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
192.168.60.30 - - [23/Jul/2025:20:47:53 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
七層
haproxy
listen webcluster_80bind *:80mode httpbalance roundrobinoption forwardfor #開啟IP透傳server web1 192.168.60.10:80 checkserver web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
nginx
http {log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
查看日志
[root@rs11 html]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:20:59:26 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:14 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:15 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
[root@rs22 ~]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:21:03:12 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:14 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:15 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:16 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
十、ACL
ACL(Access Control List)是一種強大的條件判斷機制,用于基于 HTTP 請求、響應或 TCP 連接的屬性(如 URL、請求頭、客戶端 IP 等)進行匹配,從而實現靈活的流量控制、請求路由和負載均衡決策。
- 流量過濾:允許或拒絕特定類型的請求(如封禁惡意 IP)。
- 請求路由:根據條件將請求轉發到不同的后端服務器組(如移動端請求路由到專用后端)。
ACL配置選項
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名稱 匹配規范 匹配模式 具體操作符 操作對象類型
名稱
可以使用大字母A-Z、小寫字母a-z、數字0-9、冒號:、點.、中橫線和下劃線,嚴格區分大小寫
ACL-criterion 匹配規范
1.head
[root@test1 ~]# curl -v 192.168.60.30
* Trying 192.168.60.30:80...
* Connected to 192.168.60.30 (192.168.60.30) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.60.30
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: nginx/1.20.1
< date: Sat, 26 Jul 2025 10:28:31 GMT
< content-type: text/html
< content-length: 19
< last-modified: Thu, 17 Jul 2025 08:06:05 GMT
< etag: "6878aeed-13"
< accept-ranges: bytes
<
rs11-192.168.60.10
* Connection #0 to host 192.168.60.30 left intact
hdr:用于完全匹配 HTTP 請求報文首部的指定字符串,格式為hdr(<name> (,<occ>))
,<name>
是 header 的指定信息,<occ>
表示在多值中使用的值的出現次數。
acl is_google hdr(host) -i www # 匹配Host頭為"www"的請求 -i忽略大小寫
hdr_beg:前綴匹配,即匹配 header 中指定內容的開頭,格式為hdr_beg(<name> (,<occ>))
。
acl is_api hdr_beg(path) /api # 匹配路徑以/api開頭的內容
hdr_end:后綴匹配,匹配 header 中指定內容的結尾,格式為hdr_end(<name> (,<occ>))
。
acl is_js hdr_end(path) .img # 匹配路徑以.img結尾的請求
hdr_dom:域匹配,用于匹配 header 中的域名,格式為hdr_dom(<name> (,<occ>))
。
acl pc_web_page hdr_dom(host) -i www.badidu.com # 匹配所有請求域名為www.badidu.com的請求
hdr_dir:路徑匹配,匹配 header 的 uri 路徑,格式為hdr_dir(<name> (,<occ>))
。
acl in_images hdr_dir(path) /images # 匹配路徑包含"/images"目錄的請求
hdr_len:長度匹配,匹配 header 的長度,格式為hdr_len(<name> (,<occ>))
。
acl long_cookie hdr_len(cookie) gt 500 # 匹配Cookie長度超過500的請求
hdr_reg:正則表達式匹配,使用自定義表達式 (regex) 進行模糊匹配,格式為hdr_reg(<name> (,<occ>))
。
acl ie6 hdr_reg(User-Agent) -i MSIE\ [1-6]\. #匹配IE1-6
hdr_sub:子串匹配,在 header 中的 uri 進行模糊匹配,格式為hdr_sub(<name> (,<occ>))
。
acl has_token hdr_sub(authorization) Bearer # 匹配Authorization頭包含"Bearer"的請求
2.base:string
返回第一個主機頭和請求的路徑部分的連接,該請求從主機名host開始,并在問號之前結束,對虛擬主機有用
😕/:@:/
匹配類型 | 描述 |
---|---|
base | 精確字符串匹配 |
base_beg | 前綴匹配 |
base_dir | 子目錄匹配 |
base_dom | 域名匹配 |
base_end | 后綴匹配 |
base_len | 長度匹配 |
base_reg | 正則表達式匹配 |
base_sub | 子字符串匹配 |
3.path : string
提取請求的URL路徑,該路徑從/
😕/:@:/
匹配類型 | 描述 |
---|---|
path | 精確字符串匹配 |
path_beg | 前綴匹配(請求的 URL 開頭,如 /static、/images、/img、/css) |
path_end | 后綴匹配(請求的 URL 中資源的結尾,如 .gif、.png、.css、.js、.jpg、.jpeg) |
path_dom | 域名匹配 |
path_dir | 子目錄匹配 |
path_len | 長度匹配 |
path_reg | 正則表達式匹配 |
path_sub | 子字符串匹配 |
4.src | dst
匹配類型 | 描述 |
---|---|
src | 匹配源 IP 地址或網段。 |
src_port | 匹配源端口。 |
dst | 匹配目標 IP 地址(通常是負載均衡器的 IP)。 |
dst_port | 匹配目標端口。 |
ACL-flags 匹配模式
ACL匹配模式
-i 不區分大小寫
-m 指定正則的匹配方法
-n 不做DNS解析
-u 禁止acl重名,否則多個同名ACL匹配或關
ACL-operator 具體操作符
整數操作符
操作符 含義
eq 等于
ne 不等于
gt 大于
ge 大于等于
lt 小于
le 小于等于
字串匹配
-m str 完全匹配字符串 字符串必須完全匹配模式
-m sub 包含子串 在提取的字符串中查找模式,如果其中任何一個被發現,ACL將匹配
-m beg 前綴匹配 在提取的字符串首部中查找模式,如果其中任何一個被發現,ACL將匹配
-m end 后綴匹配 將模式與提取字符串的尾部進行比較,如果其中任何一個匹配,則ACL進行匹配
-m dir 路徑目錄匹配 查看提取出來的用斜線分隔(“/”)的字符串,如其中任一個匹配,則ACL進行匹配
-m dom 域名或子域名匹配 查找提取的用點(“.”)分隔字符串,如果其中任何一個匹配,則ACL進行匹配
組合使用
與:隱式(默認)使用
或:使用“or" 或 “||"表示
否定:使用 “!” 表示
示例
if valid_src valid_port #與關系,ACL中A和B都要滿足為true,默認為與
if invalid_src || invalid_port #或,ACL中A或者B滿足一個為true
if ! invalid_src #非,取反,不滿足ACL才為true
示例
1.域名匹配
配置
frontend webcluster_80bind *:80mode http
#acl
acl web_host hdr_dom(host) www.dl.org
#host
use_backend webserver1 if web_host
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
測試
#地址解析
[root@test1 ~]# cat /etc/hosts
...
192.168.60.30 www.dl.org[root@test1 ~]# curl www.dl.org
rs11-192.168.60.10
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl www.dl.org
rs11-192.168.60.10
IP控制
配置
frontend webcluster_80bind *:80mode http
#acl
acl ip_test src 192.168.60.1
acl web_host hdr_dom(host) www.dl.org#host
use_backend webserver1 if ip_test
http-request deny if web_host#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
測試
#192.168.60.1
[C:\~]$ curl 192.168.60.30% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 19 100 19 0 0 8543 0 --:--:-- --:--:-- --:--:-- 9500
rs11-192.168.60.10
#192.168.60.88
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl www.dl.org
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
#192.168.60.66
[root@ceshi ~]# curl 192.168.60.30
rs22-192.168.60.20
匹配瀏覽器類型
frontend webcluster_80bind *:80mode http
#acl
acl user_agent_block hdr_sub(User-Agent) -i curl wget #匹配 curl wget
acl user_agent_redirect hdr_sub(User-Agent) -i Mozilla/5.0 #匹配所有類型瀏覽器#host
http-request deny if user_agent_block #拒絕curl wget
redirect prefix https://www.baidu.com if user_agent_redirect #將所有瀏覽器請求重定向至百度
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
測試
[root@test1 ~]# curl 192.168.60.30
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@test1 ~]# wget 192.168.60.30
--2025-07-26 20:06:06-- http://192.168.60.30/
Connecting to 192.168.60.30:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2025-07-26 20:06:06 ERROR 403: Forbidden.
基于后綴動靜分離
配置
frontend webcluster_80bind *:80mode http
#acl
acl url_static path_end -i .jpg .png .css .js .html
acl url_php path_end -i .php#host
use_backend webserver1 if url_static
use_backend webserver2 if url_php
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
測試
[root@ceshi ~]# curl 192.168.60.30/index.php
php 192.168.60.20
[root@ceshi ~]# curl 192.168.60.30/index.css
css 192.168.60.10
[root@ceshi ~]#
基于路徑實現動靜分離
frontend webcluster_80bind *:80mode http
#acl
acl url_static path_end -m sub /static /images /javascript
acl acl_app path_beg -m sub /api
#host
use_backend webserver1 if url_static
use_backend webserver2 if acl_app
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
測試
[root@ceshi ~]# curl 192.168.60.30/static/
static 192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/api/
api 192.168.60.20
十一、自定義錯誤頁面
haproxy默認使用的錯誤錯誤頁面
[root@haproxy ~]# rpm -ql haproxy | grep -E http$
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
自定義錯誤頁面
#打開配置文件寫入
vim /etc/haproxy/haproxy.cfg
errorfile 503 /haproxy/errorpages/503page.http#創建目錄
mkdir /haproxy/errorpages/ -p
#復制文件
cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
#修改
vim /haproxy/errorpages/503page.http
HTTP/1.0 503 Service Unavailable^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html^M
^M
<html><body><h1>服務器也需要休息</h1>
請稍后訪問
</body></html>
#重啟haproxy服務
systemctl restart haproxy.service
測試
#關閉后端服務器
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check disabledserver web2 192.168.60.20:80 check disabled# server error 192.168.60.30:8080 backup
#訪問
[root@test1 ~]# curl 192.168.60.30
<html><body><h1>服務器也需要休息</h1>
請稍后訪問
</body></html>
錯誤頁面重定向
#打開配置文件寫入
vim /etc/haproxy/haproxy.cfg
errorloc 503 https://www.163.com
十二、四層負載示例
這里以數據庫為例
haproxy
vim /etc/haproxy/haproxy.conf
listen webcluster_80bind *:3306mode tcpbalance roundrobinserver web1 192.168.60.10:3306 checkserver web2 192.168.60.20:3306 check
rs1
#安裝數據庫
dnf install mariadb-server -y
#啟動
systemctl start mariadb
#添加用戶
mysql -e "grant all on *.* to dll@'%' identified by 'dll';"
rs2
yum install mariadb-server -y
systemctl start mariadb
mysql -e "grant all on *.* to dll@'%' identified by 'dll';"
測試
[root@ceshi ~]# mysql -udll -pdll -h 192.168.60.30 -e "show variables like'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs11 |
+---------------+-------+
[root@ceshi ~]# mysql -udll -pdll -h 192.168.60.30 -e "show variables like'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs22 |
+---------------+-------+
https實現
證書制作
#創建目錄
mkdir /etc/haproxy/certs/
#制作證書
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/dl.key -x509 -days 365 -out /etc/haproxy/certs/dl.crt
#制作.pem文件
cat dl.key dl.crt >dl.pem
haproxy配置
frontend webserverbind *:80redirect scheme https if !{ ssl_fc } #全站加密#redirect scheme https:將請求的協議從 HTTP 重定向為 HTTPS。#if !{ ssl_fc }:條件判斷,! 表示否定,{ ssl_fc } 檢查當前連接是否使用 SSL/TLS。#即:僅對非 HTTPS 請求執行重定向。mode httpuse_backend webclusterfrontend webserver-httpsbind *:443 ssl crt /etc/haproxy/certs/dl.pem #指定證書文件mode httpuse_backend webclusterbackend webclustermode httpbalance roundrobinserver web1 192.168.60.10:80 checkserver web2 192.168.60.20:80 check
測試
[root@test1 ~]# curl -k https://192.168.60.30
php 192.168.60.20
[root@test1 ~]# curl -k https://192.168.60.30
rs11-192.168.60.10