haproxy七層代理(知識點+相關實驗部署)

目錄

1.負載均衡介紹

1.1?什么是負載均衡

1.2?為什么用負載均衡

1.3 負載均衡類型

1.3.1 四層負載均衡

1.3.2 七層負載均衡

1.3.3 四層和七層的區別

2.haproxy簡介

2.1 haproxy主要特性

2.2?haproxy的優點與缺點

3.haproxy的安裝和服務信息

3.1 實驗環境

3.1.1 haproxy最簡單配置

3.2 haproxy的基本配置信息

3.2.1 global配置

3.2.1.1 global 配置參數說明

3.2.1.2 多進程和線程

3.2.2?proxies配置

3.2.2.1?Proxies配置-defaults

3.2.2.2?Proxies配置-frontend

3.2.2.3?Proxies配置-backend

?3.2.2.4?Proxies配置-listen(簡化配置)?

3.3 socat 工具

3.3.1 實例

4.haproxy的算法

4.1 靜態算法

4.1.1?static-rr

4.1.2 first

4.2 動態算法

4.2.1?roundrobin

4.2.2?leastconn?

4.3 其他算法

4.3.1?source

4.3.1.1?map-base?取模法

4.3.1.2 一致性hash

4.3.2 uri

4.3.3 url_param

4.3.4? hdr

?4.4 算法總結

5.高級功能及配置

5.1 基于cookie的會話保持

5.2 HAProxy狀態頁

狀態頁配置項

5.3 IP透傳

5.3.1 七層IP透傳

5.3.2?四層IP透傳

5.4 ACL

5.4.1 ACL配置選項

?5.4.1.1?ACL-Name 名稱

5.4.1.2?ACL-criterion 匹配規范

5.4.1.3 ACL-flags 匹配模式

5.4.1.4 ACL-operator 具體操作符

5.4.1.5 ACL-value 操作對象?

5.4.2 多個ACL的組合調用方式

5.4.3 ACL示例

5.4.3.1?域名匹配

5.4.3.2?基于源IP或子網調度訪問

5.4.3.3?基于源地址的訪問控制

?編輯?5.4.3.4?匹配瀏覽器類型

5.4.3.5?基于文件后綴名實現動靜分離

5.4.3.6?匹配訪問路徑實現動靜分離

5.5 自定義HAProxy 錯掉誤界面

5.5.1 基于自定義的錯誤頁面文件

5.5.2 基于http重定向錯誤頁面

5.6 HAProxy 四層負載

5.7 HAProxy https 實現

5.7.1 證書制作

5.7.2 將證書導入haproxy配置


1.負載均衡介紹

1.1?什么是負載均衡

????????負載均衡:Load Balance,簡稱LB,是一種服務或基于硬件設備等實現的高可用反向代理技術,負載均衡將特定的業務(web服務、網絡流量等)分擔給指定的一個或多個后端特定的服務器或設備,從而提高了公司業務的并發處理能力、保證了業務的高可用性、方便了業務后期的水平動態擴展。

1.2?為什么用負載均衡

  • Web服務器的動態水平擴展-->對用戶無感知
  • 增加業務并發訪問及處理能力-->解決單服務器瓶頸問題
  • 節約公網IP地址-->降低IT支出成本
  • 隱藏內部服務器IP-->提高內部服務器安全性
  • 配置簡單-->固定格式的配置文件
  • 功能豐富-->支持四層和七層,支持動態下線主機
  • 性能較強-->并發數萬甚至數十萬

1.3 負載均衡類型

1.3.1 四層負載均衡

  1. 通過ip+port決定負載均衡的去向。
  2. 對流量請求進行NAT處理,轉發至后臺服務器。
  3. 記錄tcpudp流量分別是由哪臺服務器處理,后續該請求連接的流量都通過該服務器處理。
  4. 支持四層的軟件:
    • lvs:重量級四層負載均衡器。
    • Nginx:輕量級四層負載均衡器,可緩存。(nginx四層是通過upstream模塊)
    • Haproxy:模擬四層轉發。

1.3.2 七層負載均衡

  1. 通過虛擬URL或主機IP進行流量識別,根據應用層信息進行解析,決定是否需要進行負載均衡。
  2. 代理后臺服務器與客戶端建立連接,如nginx可代理前后端,與前端客戶端tcp連接,與后端服務器建立tcp連接。
  3. 支持7層代理的軟件:
    1. Nginx:基于http協議(nginx七層是通過proxy_pass)?
    2. Haproxy:七層代理,會話保持、標記、路徑轉移等。

1.3.3 四層和七層的區別

  1. 分層位置:四層負載均衡在傳輸層及以下,七層負載均衡在應用層及以下。
  2. 性能 :四層負載均衡架構無需解析報文消息內容,在網絡吞吐量與處理能力上較高;七層可支持解析應用層報文消息內容,識別URLCookieHTTP header等信息。
  3. 原理 :四層負載均衡是基于ip+port;七層是基于虛擬的URL或主機IP等。
  4. 功能類比:四層負載均衡類似于路由器;七層類似于代理服務器。
  5. 安全性:四層負載均衡無法識別DDoS攻擊;七層可防御SYN Cookie/Flood攻擊。

????????舉個通俗的例子說明:四層負載均衡就像銀行的自助排號機,每一個到銀行的客戶,根據排號機的順序,選擇對應的窗口接受服務;而七層負載均衡像銀行大堂經理,先確認客戶需要辦理的業務,再安排排號。這樣辦理理財、存取款等業務的客戶,會去不同的地方排隊,加快了業務辦理流程。

2.haproxy簡介

????????HAProxy是法國開發者 威利塔羅(Willy Tarreau) 2000年使用C語言開發的一個開源軟件,是一款具備高并發(萬級以上)、高性能的TCPHTTP負載均衡器。支持基于cookie的持久性,自動故障切換,支持正則表達式及web狀態統計。
企業版網站:https://www.haproxy.com
社區版網站:http://www.haproxy.org
github:https://github.com/haprox

2.1 haproxy主要特性

  • 高性能負載均衡: HAProxy通過優化的事件驅動引擎,能夠以最小的系統資源開銷處理大量并發請求。它支持多種負載均衡算法,如輪詢、最少連接、源IP哈希等,可根據實際業務需求靈活配置
  • 健康檢查與故障恢復: HAProxy具備完善的后端服務器健康檢查機制,可以根據響應時間、錯誤率等因素自動剔除不健康的后端節點,并在節點恢復時重新將其加入到服務池中,確保服務連續性
  • 會話保持與親和性: 為了保證用戶的會話一致性,HAProxy支持基于cookie或源IP地址的會話保持功能,確保同一客戶端的請求被轉發到同一臺后端服務器進行處理
  • 安全性與SSL卸載: HAProxy支持SSL/TLS加密傳輸,可對HTTPS流量進行解密并透明地分發至后端服務器,同時也能終止SSL連接以減輕服務器的加密計算壓力
  • 高級路由與策略: 根據HTTP請求頭、URL路徑、內容類型等條件,HAProxy可以執行復雜的路由規則和ACL策略,使得負載均衡更加智能化和精準化
  • 日志記錄與監控: HAProxy提供豐富的日志記錄選項,可通過syslog、CSV格式輸出等方式收集統計數據,便于運維人員實時監控系統狀態和性能指標

2.2?haproxy的優點與缺點

優點:

  • 高性能:Haproxy是專門為高性能設計的,具有低延遲和并發處理能力。
  • 靈活:Haproxy具有豐富的配置選項,可以滿足各種復雜的負載均衡需求。
  • 可擴展性:Haproxy支持插件擴展,可以輕松地集成到現有的系統中。
  • 安全性:Haproxy提供了SSL/TLS加密、訪問控制列表(ACL)等安全功能。

缺點:

  • 配置復雜:Haproxy的配置可能比其他一些負載均衡器更復雜,需要一定的學習和經驗。
  • 成本較高:Haproxy是一款商業軟件,需要購買許可證才能使用。

3.haproxy的安裝和服務信息

3.1 實驗環境

主機名IP角色
haproxyNAT:172.25.254.100haproxy
RS1NAT:172.25.254.10真實服務器
RS2NAT:172.25.254.20真實服務器

3.1.1 haproxy最簡單配置

(1)所有主機關閉防火墻和selinux(包括haproxy)

命令:
# 關閉防火墻
systemctl disable --now firewalld.service
# 關閉selinux
grubby --update-kernel ALL --args selinux=0

(2)兩臺RS安裝nginx,模擬提供服務

RS1
[root@RS1 ~]# dnf install nginx -y
# 生成默認測試頁
[root@RS1 ~]# echo "RS1 - 172.25.254.10" > /usr/share/nginx/html/index.html
# 開啟服務
[root@RS1 ~]# systemctl enable --now nginx.serviceRS2
[root@RS2 ~]# dnf install nginx -y
[root@RS2 ~]# echo "RS2 - 172.25.254.20" > /usr/share/nginx/html/index.html
[root@RS2 ~]# systemctl enable --now nginx.service

?訪問測試:

(3)安裝haproxy并配置相應參數

[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg**********上面內容省略**********
#---------------------------------------------------------------------
# custom web cluster
#---------------------------------------------------------------------
# 設定前端
frontend webclusterbind    *:80mode    httpbalance roundrobinuse_backend webserver# 設定后端
backend webserverserver web1 172.25.254.10:80server web2 172.25.254.20:80# 前后端合并
#listen webcluster
#   bind *:80
#   mode http
#   balance roundrobin
#    server  web1 192.168.0.10:80
#    server  web2 192.168.0.20:80開啟服務
[root@haproxy ~]# systemctl enable --now haproxy.service

?兩種寫法挑一種即可,效果一致,兩種都寫的記得把其中一種注釋掉

開啟服務后查看端口,可以看到80端口已開啟:

(4)測試

在本地終端進行訪問測試

命令:
# 連續訪問10次
for i in {1..10};do curl 172.25.254.100;done

3.2 haproxy的基本配置信息

啟動文件: /lib/systemd/system/haproxy.service

主配置目錄: /etc/haproxy/

主配置文件: /etc/haproxy/haproxy.cfg

子配置目錄: /etc/haproxy/conf.d

HAProxy 的配置文件haproxy.cfg由兩大部分組成,分別是:

global:全局配置段

  • 進程及安全配置相關的參數
  • 性能調整相關參數
  • Debug參數

proxies:代理配置段

  • defaults:為frontend, backend, listen提供默認配置
  • frontend:前端,相當于nginx中的server {}
  • backend:后端,相當于nginx中的upstream {}
  • listen:同時擁有前端和后端配置,配置簡單,生產推薦使用

3.2.1 global配置

3.2.1.1 global 配置參數說明

參數名數值功能
log127.0.0.1 local2定義全局的syslog服務器,最多定義兩個,需要開啟UDP協議
chroot/var/lib/haproxy指定運行目錄
pidfile/var/run/haproxy.pid指定pid文件
maxconn4000指定最大連接數
userhaproxy指定haproxy的運行用戶
grouphaproxy指定haproxy的運行組
stats socket/var/lib/haproxy/stats指定haproxy的套接字文件
nbproc2指定Haproxy的work進程數量,默認是1個
cpu-map1 0指定第1個work進程綁定第1個cpu核心
cpu-map2 1指定第2個work進程綁定第2個cpu核心
nbthread(與nbproc互斥)2指定haproxy的線程數量,默認每個進程一個線程
maxsslconn100000每個haproxy進程ssl最大連接數,用于haproxy
maxconnrate100指定每個客戶端每秒建立連接的最大數量
3.2.1.2 多進程和線程

(1)開啟多進程

nbproc      2    # 啟用多進程
# 進程和cpu核心綁定防止cpu抖動從而減少系統資源消耗
cpu-map     1 0  # 1 表示第一個進程,0表示第一個cpu核心
cpu-map     2 1  # 2 表示第二個進程,1表示第二個cpu核心編輯完配置文件后記得重啟服務
[root@haproxy ~]# systemctl restart haproxy.service

????????最后兩行不要亂添,因為作者的虛擬機的CPU有兩個核心所以可以這么寫,自己做的時候看看自己的虛擬機配置

?查看多進程結果:

[root@haproxy ~]# pstree -p | grep haproxy

?

(2)開啟多線程

 nbthread    2 # 啟用多線程老樣子,記得重啟服務
[root@haproxy ~]# systemctl restart haproxy.service

??查看多線程結果:

[root@haproxy ~]# pstree -p | grep haproxy|-haproxy(27963)---haproxy(27965)---{haproxy}(27966)
[root@haproxy ~]# cat /proc/27965/status

3.2.2?proxies配置

參數
類型
作用
defaults
proxies
默認配置項,針對以下的frontendbackendlisten生效,可以多個name也可以沒有name。
frontend
proxies
前端servername,類似于Nginx的一個虛擬主機 serverLVS服務集群。
backend
proxies
后端服務器組,類似于nginxupstreamLVS中的RS服務器。
listen
proxies
frontendbackend合并在一起配置,相對于frontendbackend配置更簡潔,生產常用
3.2.2.1?Proxies配置-defaults

配置名數值功能
modehttp
HAProxy實例使用的連接協議
logglobal

指定日志地址和記錄日志的設備

此處的 global?表示使用 global配置段中設定的log值。

optionhttplog

日志記錄選項

此處的 httplog 表示記錄與 HTTP 會話相關的各種屬性值
optiondontlognulldontlognull 表示不記錄空會話連接日志
option http-server-close等待客戶端完整HTTP請求的時間,此處等待10s
option forwardforexcept 127.0.0.0/8透傳客戶端真實IP到后端Web服務器;except 127.0.0.0/8:排除內網IP
optionredispatch
當server id對應的服務器掛掉后,強制定向到其他健康的服務器,重新派發(默認只重試一次)
optionhttp-keep-alive啟用HTTP長連接支持,即會話保持
retries3連接后端服務器失敗時的重試次數
timeout http-request10s等待客戶端請求完全被接收和處理的最長時間
timeout queue1m請求在隊列中等待的最長時間
timeout connect10s連接后端服務器的超時時間
timeout client1m客戶端空閑超時時間,即允許客戶端處于既不接收也不發送數據的非活動時間
timeout server1m服務器空閑超時時間,即允許服務器處于既不接收也不發送數據的非活動時間
timeout http-keep-alive10sHTTP長連接的空閑超時時間
timeout check10s后端服務器健康檢查的超時時間
maxconn3000每個進程允許的最大并發連接數
default-serverinter 1000 weight 3為所有后端服務器設置默認參數 inter 1000 表示健康檢查間隔為 1秒 weight 3 表示默認權重為 3
3.2.2.2?Proxies配置-frontend

frontend配置參數:

bind:指定HAProxy的監聽地址,可以是IPV4IPV6,可以同時監聽多個IP或端口,可同時用于listen字段中
#?格式:
bind [<address>]:<port_range> [, ...] [param*]
#?注意:如果需要綁定在非本機的IP,需要開啟內核參數:net.ipv4.ip_nonlocal_bind=1
backlog <backlog> #針對所有server配置,當前端服務器的連接數達到上限后的后援隊列長度(注:不支持backend)

?frontend配置示例:

因為之前在做?haproxy最簡單配置 時已經配置過,這里直接截圖

3.2.2.3?Proxies配置-backend
  • 定義一組后端服務器,backend服務器將被frontend進行調用。
  • 注意: backend 的名稱必須唯一,并且必須在listenfrontend中事先定義才可以使用,否則服務無法啟動
配置名功能
mode http|tcp
指定負載協議類型,和對應的frontend必須一致
option
配置選項
server
定義后端real server,必須指定IP和端口

server配置

配置項描述
check

對指定 real 進行健康狀態檢查。若不添加此設置,默認不開啟檢查功能。若 check 后無其他配置,也可啟用檢查功能。

默認對相應的后端服務器 IP 和端口,利用 TCP 連接進行周期性健康性檢查。注意必須指定端口才能實現健康性檢查。

addr <IP>可指定的健康狀態監測 IP,可以是專門的數據網段,減少業務網絡的流量。
port <num>指定的健康狀態監測端口。
inter <num>健康狀態檢查間隔時間,默認 2000 ms。
fall <num>后端服務器從線上轉為線下的檢查的連續失效次數,默認為 3。
rise <num>后端服務器從下線恢復上線的檢查的連續有效次數,默認為 2。
weight <weight>默認為 1,最大值為 256,0(狀態為藍色)表示不參與負載均衡,但仍接受持久連接。
backup將后端服務器標記為備份狀態,只在所有非備份主機 down 機時提供服務,類似 Sorry Server。
disabled將后端服務器標記為不可用狀態,即維護狀態,除了持久模式,將不再接受連接,狀態為深黃色,優雅下線,不再接受新用戶的請求。
redirect prefix?
http://www.baidu.com/
將請求臨時(302)重定向至其它 URL,只適用于 http 模式。
maxconn <maxconn>當前后端 server 的最大并發連接數。

?backend配置示例:

?3.2.2.4?Proxies配置-listen(簡化配置)?
????????使用listen替換 frontendbackend的配置方式,可以簡化設置,通常只用于TCP協議的應
listen配置示例(這里是被注釋掉了):

3.3 socat 工具

????????對服務器動態權重和其它狀態可以利用 socat工具進行調整,Socat 是 Linux 下的一個多功能的網絡工具,名字來由是Socket CAT,相當于netCAT的增強版.Socat 的主要特點就是在兩個數據流之間建立雙向通道,且支持眾多協議和鏈接方式。如 IP、TCP、 UDP、IPv6、Socket文件等

該工具系統默認沒有,需要安裝

[root@haproxy ~]# dnf install socat -y

使用前還需要修改配置文件(修改完后記得重啟服務):

3.3.1 實例

以下實驗除了最后一個,都不必重啟服務,因為socat全部都是用熱處理(類似游戲的不停機更新)

(1)查看集群狀態

[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats

(2)查看集群權重

[root@haproxy ~]# echo get weight webserver/web1 | socat stdio /var/lib/haproxy/stats
[root@haproxy ~]# echo get weight webserver/web2 | socat stdio /var/lib/haproxy/stats

(3)修改集群權重

修改web1的權重為2
[root@haproxy ~]# echo "set weight webserver/web1 2 " | socat stdio /var/lib/haproxy/stats

?在測試端查看效果:

此時再次查看集群權重:

?(4)上下線真實服務器

下線web1后端服務器
[root@haproxy ~]# echo "disable server webserver/web1 " | socat stdio /var/lib/haproxy/stats

?在測試端查看效果,此時訪問的全是web2:

再次將web1服務器上線
[root@haproxy ~]# echo "enable server webserver/web1 " | socat stdio /var/lib/haproxy/stats

再次測試:

(5)針對多進程處理方法

如果開啟多進程那么我們在對進程的sock文件進行操作時其對進程的操作時隨機的

如果需要指定操作進程那么需要用多soct文件方式來完成

global# to have these messages end up in /var/log/haproxy.log you will# need to:## 1) configure syslog to accept network log events.  This is done#    by adding the '-r' option to the SYSLOGD_OPTIONS in#    /etc/sysconfig/syslog## 2) configure local2 events to go to the /var/log/haproxy.log#   file. A line like the following can be added to#   /etc/sysconfig/syslog##    local2.*                       /var/log/haproxy.log#log         127.0.0.1 local2chroot      /var/lib/haproxypidfile     /var/run/haproxy.pidmaxconn     4000user        haproxygroup       haproxydaemonnbproc      2cpu-map     1 0cpu-map     2 1# turn on stats unix socketstats socket /var/lib/haproxy/stats1 mode 600 level admin process 1stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2# utilize system-wide crypto-policiesssl-default-bind-ciphers PROFILE=SYSTEMssl-default-server-ciphers PROFILE=SYSTEM

修改完配置文件后重啟服務
[root@haproxy ~]# systemctl restart haproxy.service

查看結果

測試,可以看到原來的文件 stats 已經無法使用,但是新的stats1和stats2可以使用:

4.haproxy的算法

HAProxy通過固定參數 balance 指明對后端服務器的調度算法

balance參數可以配置在listenbackend選項中。

HAProxy的調度算法分為靜態動態調度算法

有些算法可以根據參數在靜態和動態算法中相互轉換。

4.1 靜態算法

????????靜態算法:按照事先定義好的規則輪詢公平調度,不關心后端服務器的當前負載、連接數和響應速度等,且無法實時修改權重(?只能為?0?和?1,?不支持其它值?)?,只能靠重啟?HAProxy?生效。

4.1.1?static-rr

  • 不支持運行時利用socat進行權重的動態調整(只支持0和1,不支持其它值)
  • 不支持端服務器慢啟動
  • 其后端主機數量沒有限制,相當于LVS中的 wrr

慢啟動是指在服務器剛剛啟動上不會把他所應該承擔的訪問壓力全部給它,而是先給一部分,當沒問題后在給一部分

示例:

?重啟服務后測試:

4.1.2 first

  • 根據服務器在列表中的位置,自上而下進行調度
  • 其只會當第一臺服務器的連接數達到上限,新請求才會分配給下一臺服務
  • 其會忽略服務器的權重設置
  • 不支持用socat進行動態修改權重,可以設置0和1,可以設置其它值但無效

?示例:

重啟服務后測試:

4.2 動態算法

  • 基于后端服務器狀態進行調度適當調整,
  • 新請求將優先調度至當前負載較低的服務器
  • 權重可以在haproxy運行時動態調整無需重啟

4.2.1?roundrobin

  1. 基于權重的輪詢動態調度算法,
  2. 支持權重的運行時調整,不同于 lvs 中的 rr 輪訓模式,
  3. HAProxy 中的 roundrobin 支持慢啟動 ( 新加的服務器會逐漸增加轉發數 ) ,
  4. 其每個后端 backend 中最多支持 4095 個 real server ,
  5. 支持對 real server 權重動態調整,
  6. roundrobin 為默認調度算法 , 此算法使用廣泛

????優先把流量給權重高且負載小的主機,以負載為主

4.2.2?leastconn?

  • leastconn加權的最少連接的動態
  • 支持權重的運行時調整和慢啟動(相當于LVS的wlc),即:根據當前連接最少的后端服務器而非權重進行優先調度(新客戶端連接)【當兩個主機的連接數都差不多的時候給權重高的,權重是次考慮的】
  • 比較適合長連接的場景使用,比如:MySQL等場景。

4.3 其他算法

其它算法即可作為靜態算法,又可以通過選項成為動態算法

4.3.1?source

源地址 hash ,基于用戶源地址 hash 并將請求轉發到后端服務器,后續同一個源地址請求將被轉發至同一 個后端web 服務器。此方式當后端服務器數據量發生變化時,會導致很多用戶的請求轉發至新的后端服務器,默認為靜態方式,但是可以通過hash-type 支持的選項更改這個算法一般是在不插入 Cookie 的 TCP模式下使用,也可給拒絕會話cookie 的客戶提供最好的會話粘性,適用于 session 會話保持但不支持 cookie和緩存的場景源地址有兩種轉發客戶端請求到后端服務器的服務器選取計算方式,分別是取模法和一致性hash

??示例:

?重啟服務后測試:

4.3.1.1?map-base?取模法

map-based :取模法,對 source 地址進行 hash 計算,再基于服務器總權重的取模,最終結果決定將此請求轉發至對應的后端服務器。
此方法是靜態的,即不支持在線調整權重,不支持慢啟動,可實現對后端服務器均衡調度
缺點是當服務器的總權重發生變化時,即有服務器上線或下線,都會因總權重發生變化而導致調度結果 整體改變 ?, hash-type 指定的默值為此算法
所謂取模運算,就是計算兩個數相除之后的余數, 10%7=3, 7%4=3
map-based 算法:基于權重取模, hash(source_ip)% 所有后端服務器相加的總權重
比如當源hash值時1111,1112,1113,三臺服務器a b c的權重均為1,
即abc的調度標簽分別會被設定為 0 1 2(1111%3=1,1112%3=2,1113%3=0)
1111 ----- > nodeb
1112 ------> nodec
1113 ------> nodea
如果a下線后,權重數量發生變化
1111%2=1,1112%2=0,1113%2=1
1112和1113被調度到的主機都發生變化,這樣會導致會話丟失

4.3.1.2 一致性hash

一致性哈希,當服務器的總權重發生變化時,對調度結果影響是局部的,不會引起大的變動hash (o) mod n
該hash算法是動態的,支持使用socat等工具進行在線權重調整,支持慢啟動

算法

  1. key1=hash(source_ip)%(2^32)
  2. keyA=hash(后端服務器虛擬ip)%(2^32) [0—4294967295]
  3. 將key1和keyA都放在hash環上,將用戶請求調度到離key1最近的keyA對應的后端服務器

hash 環偏斜問題
增加虛擬服務器 IP 數量,比如:一個后端服務器根據權重為 1 生成 1000 個虛擬 IP ,再 hash 。而后端服務器權 重為2 則生成 2000 的虛擬 IP ,再 bash, 最終在 hash 環上生成 3000 個節點,從而解決 hash 環偏斜問題

hash對象?

Hash對象到后端服務器的映射關系

一致性hash示意圖

后端服務器在線與離線的調度方式

4.3.2 uri

基于對用戶請求的 URI 的左半部分或整個 uri 做 hash ,再將 hash 結果對總權重進行取模后
根據最終結果將請求轉發到后端指定服務器
適用于后端是緩存服務器場景
默認是靜態算法,也可以通過 hash-type 指定 map-based 和 consistent ,來定義使用取模法還是一致性hash
注意:此算法基于應用層,所以只支持 mode http ,不支持 mode tcp

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
左半部分: /<path>;<params>
整個 uri : /<path>;<params>?<query>#<frag>

?

4.3.3 url_param

url_param 對用戶請求的 url 中的 params 部分中的一個參數 key 對應的 value 值作 hash 計算,并由服務器總權重相除以后派發至某挑出的服務器, 后端搜索同一個數據會被調度到同一個服務器,多用與電商
通常用于追蹤用戶,以確保來自同一個用戶的請求始終發往同一個real server
如果無沒 key ,將按 roundrobin 算法

4.3.4? hdr

針對用戶每個 http 頭部 (header) 請求中的指定信息做 hash ,
此處由 name 指定的 http 首部將會被取出并做 hash 計算,
然后由服務器總權重取模以后派發至某挑出的服務器,如果無有效值,則會使用默認的輪詢調度。

?4.4 算法總結

# 靜態
static-rr--------->tcp/http
first------------->tcp/http
# 動態
roundrobin-------->tcp/http
leastconn--------->tcp/http
# 以下靜態和動態取決于 hash_type 是否 consistent
source------------>tcp/http
uri--------------->http
url_param--------->http
hdr--------------->http
各算法使用場景
first ? ? ? ? ? ? ? ? ? ? ?#使用較少
static-rr ? ? ? ? ? ? ? ?#做了 session 共享的 web 集群
roundrobin ? ? ? ? ? #做了 session 共享的 web 集群
leastconn ? ? ? ? ? ? #數據庫
source ? ? ? ? ? ? ? ? ?#基于客戶端公網IP的會話保持
Uri--->http ? ? ? ? ? ?#緩存服務器, CDN 服務商,藍汛、百度、阿里云、騰訊
url_param--->http # 可以實現 session 保持
hdr ? ? ? ? ? ? ? ? ? ? ? ?#基于客戶端請求報文頭部做下一步處理

5.高級功能及配置

5.1 基于cookie的會話保持

????????cookie value:為當前server指定cookie值,實現基于cookie的會話黏性,相對于基于 source 地址hash調度算法對客戶端的粒度更精準,但同時也加大了haproxy負載,目前此模式使用較少,已經被session共享服務器代替

注意:不支持 tcp mode,使用 http mode

配置選項?

cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
name : ? ? #cookie 的 key 名稱,用于實現持久連接
insert : ? ? # 插入新的 cookie, 默認不插入 cookie
indirect : # 如果客戶端已經有 cookie, 則不會再發送 cookie 信息
nocache: ? # 當 client 和 hapoxy 之間有緩存服務器(如: CDN )時,不允許中間緩存器緩存 cookie: ? ?#因為這會導致很多經過同一個 CDN 的請求都發送到同一臺后端服務器

?這里使用listen簡化配置:

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind *:80mode httpbalance roundrobincookie WEBCOOKIE insert nocache indirectserver  web1 172.25.254.10:80 cookie servera check inter 3s fall 3server  web2 172.25.254.20:80 cookie serverb check inter 3s fall 3重啟服務
[root@haproxy ~]# systemctl restart haproxy.service

測試:

瀏覽器訪問haproxy的ip,網頁刷新數次后依舊訪問的是RS1

5.2 HAProxy狀態頁

狀態頁配置項

stats enable ? ? ? ? ? ? ? ? ? ? ? # 基于默認的參數啟用 stats page
stats hide-version ? ? ? ? ? ? ?# 將狀態頁中 haproxy 版本隱藏
stats refresh <delay> ? ? ? ?# 設定自動刷新時間間隔,默認不自動刷新
stats uri <prefix> ? ? ? ? ? ? ? # 自定義 stats page uri ,默認值: /haproxy?stats
stats auth <user>:<passwd> # 認證時的賬號和密碼,可定義多個用戶 , 每行指定一個用戶
# 默認: no authentication
stats admin { if | unless } <cond> # 啟用 stats page 中的管理功能

?啟用狀態頁

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfglisten haproxystatusmode httpbind *:9999stats enablestats refresh 3log   globalstats uri /statusstats auth guanai:guanai重啟服務
[root@haproxy ~]# systemctl restart haproxy.service

測試:

此時關閉RS1上的nginx

等狀態頁刷新,可以看到web1變紅了:

重新上線

恢復正常:

5.3 IP透傳

????????web服務器中需要記錄客戶端的真實IP地址,用于做訪問統計、安全防護、行為分析、區域排行等場景。

5.3.1 七層IP透傳

七層IP透傳只要打開forwardfor該參數即可,會自動透傳過來

訪問測試:

在RS上查看日志,可以看到,訪問端的真實IP透過來了:

5.3.2?四層IP透傳

想要看到效果需要修改該參數,加“send-proxy”是為了讓haproxy走四層走得更徹底(記得重啟服務

編輯/etc/nginx/nginx.conf文件
[root@RS1 ~]# vim /etc/nginx/nginx.conf
啟用此項,將無法直接訪問此網站,只能通過四層代理訪問

重啟nginx和haproxy服務后再次訪問:

再次查看日志,可以看到,訪問端的真實IP透不過來了:

(第一行命令用于清除日志,在訪問測試之前做,避免之前七層IP透傳產生的日志影響)

解決辦法:

在/etc/nginx/nginx.conf文件加入該參數(兩個RS都要做

編輯/etc/nginx/nginx.conf文件
[root@RS1 ~]# vim /etc/nginx/nginx.conf'"$proxy_protocol_addr"'編輯完后重啟服務
[root@RS2 ~]# systemctl restart nginx.service

再次查看日志,對比兩次訪問結果的日志,可以看到,訪問端的真實IP透過來了:

5.4 ACL

訪問控制列表ACLAccess Control Lists

是一種基于包過濾的訪問控制技術

它可以根據設定的條件對經過服務器傳輸的數據包進行過濾(條件匹配)即對接收到的報文進行匹配和過濾,基于請求報文頭部中的源地址、源端口、目標地址、目標端口、請求方法、URL、文件后綴等信息內容進行匹配并執行進一步操作,比如允許其通過或丟棄。

在做之前把之前做四層IP透傳的配置改回來,不然會訪問失敗(改完記得重啟服務)

80后面的這段配置刪掉,要不然

5.4.1 ACL配置選項

#acl來定義或聲明一個acl
acl? ? <aclname>? ? ? <criterion>? ? ? ? [flags]? ? ? ? ? ?[operator]? ? ? ? ? ? ? [<value>]
acl? ? ? ? ?名稱? ? ? ? ? ? ?匹配規范? ? ? ?匹配模式? ? ? ? 具體操作符? ? ? ? ?操作對象類型
?5.4.1.1?ACL-Name 名稱

acl? ? test? ? ?path_end? ? ?-m? ? sub? ? /a
#ACL名稱,可以使用大字母A-Z、小寫字母a-z、數字0-9、冒號:、點.、中橫線和下劃線,并且嚴格區分大小寫,比如:my_aclMy_Acl就是兩個完全不同的acl5.8.1.2 ACL-criterion
5.4.1.2?ACL-criterion 匹配規范

定義ACL匹配規范,即:判斷條件

hdr string,提取在一個HTTP請求報文的首部
hdr[<name> [<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出現次數
hdr_beg[<name> [<occ>]]):前綴匹配,header中指定匹配內容的begin
hdr_end[<name> [<occ>]]):后綴匹配,header中指定匹配內容end
hdr_dom[<name> [<occ>]]):域匹配,header中的domhost
hdr_dir[<name> [<occ>]]):路徑匹配,headeruri路徑
hdr_len[<name> [<occ>]]):長度匹配,header的長度匹配
hdr_reg[<name> [<occ>]]):正則表達式匹配,自定義表達式(regex)模糊匹配
hdr_sub[<name> [<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 報文中a/b/c也會匹配
#示例:
hdr(<string>) 用于測試請求頭部首部指定內容
hdr_dom(host) 請求的host名稱,如 www.guanai.com
hdr_beg(host) 請求的host開頭,如 www. img. video. download. ftp.
hdr_end(host) 請求的host結尾,如 .com .net .cn
#示例:
acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent
#有些功能是類似的,比如以下幾個都是匹配用戶請求報文中host的開頭是不是www
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.
base : string
#返回第一個主機頭和請求的路徑部分的連接,該請求從主機名開始,并在問號之前結束,對虛擬主機有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
path : string
#提取請求的URL路徑,該路徑從第一個斜杠開始,并在問號之前結束(無主機部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
path : exact string match
path_beg : prefix match #請求的URL開頭,如/static/images/img/css
path_end : suffix match #請求的URL中資源的結尾,如 .gif .png .css .js .jpg .jpeg
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
#示例:
path_beg -i /haproxy-status/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom timinglee
url : string
#提取請求中的整個URL
url exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
dst #目標IP
dst_port #目標PORT
src #IP
src_port #PORT
#示例:
acl invalid_src src 10.0.0.7 192.168.1.0/24
acl invalid_src src 172.16.0.0/24
acl invalid_port src_port 0:1023
status : integer #返回在響應報文中的狀態碼
#七層協議
acl valid_method method GET HEAD
http-request deny if ! valid_method
5.4.1.3 ACL-flags 匹配模式

ACL匹配模式:

-i 不區分大小寫

-m 使用指定的正則表達式匹配方法

-n 不做DNS解析

-u 禁止acl重名,否則多個同名ACL匹配或關系

5.4.1.4 ACL-operator 具體操作符

ACL 操作符:

整數比較:eqgegtlelt
字符比較:
- exact match (-m str) :字符串必須完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一個被發現,ACL將匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一個被發現,ACL將匹配
- suffix match (-m end) :將模式與提取字符串的尾部進行比較,如果其中任何一個匹配,則ACL進行匹配
- subdir match (-m dir) :查看提取出來的用斜線分隔(“/")的字符串,如其中任一個匹配,則ACL進行匹配
- domain match (-m dom) :查找提取的用點(“.")分隔字符串,如果其中任何一個匹配,則ACL進行匹配
5.4.1.5 ACL-value 操作對象?

value的類型

The ACL engine can match these types against patterns of the following types :
- Boolean #布爾值
- integer or integer range #整數或整數范圍,比如用于匹配端口范圍
- IP address / network #IP地址或IP范圍, 192.168.0.1 ,192.168.0.1/24
- string--> www.guanai.com
exact #精確比較
substring #子串
suffix #后綴比較
prefix #前綴比較
subdir #路徑, /wp-includes/js/jquery/jquery.js
domain #域名,www.guanai.com
- regular expression #正則表達式
- hex block #16進制

5.4.2 多個ACL的組合調用方式

多個ACL的邏輯處理

與:隱式(默認)使用
或:使用“or" “||"表示
否定:使用 "!" 表示

多個ACL調用方式:

#例子:
if A B? ? #?與關系,ACLAB都要滿足為true,默認為與
if A || B #?或,ACLA或者B滿足一個為true
if ! A? ? ?#?非,取反,不滿足ACL才為true

5.4.3 ACL示例

5.4.3.1?域名匹配

?這里使用前后端的方式

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     http# 基于域名www.loving_eyes.com匹配acl web_host hdr_dom(host) www.loving_eyes.com# 如果符合ACL規則:web_host,使用服務器webserver1use_backend webserver1 if web_host# 默認使用服務器webserver2default_backend webserver2backend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

測試機做本地域名解析,不然訪問域名會不成功:

測試機ip

[root@webservera html]# vim /etc/hosts

測試:

可以看到訪問ip走的是RS2,訪問域名走的是RS1

5.4.3.2?基于源IP或子網調度訪問

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     http#基于172.25.254.111這個IP和192.168.0.0/24這個網段進行匹配acl ip_test src 172.25.254.111 192.168.0.0/24use_backend webserver1 if ip_testdefault_backend webserver2backend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

?測試:

可以看到測試機符合ACL走的是RS1,本地終端不符合ACL走的是RS2

5.4.3.3?基于源地址的訪問控制

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     http#acl web_host hdr_dom(host) www.loving_eyes.comacl ip_test src 172.25.254.111 192.168.0.0/24acl bad_ip src 172.25.254.1use_backend webserver1 if ip_testdefault_backend webserver2# 符合bad_ip策略的源地址被拒絕以http的方式訪問haproxyhttp-request deny if bad_ipbackend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

?測試:

測試機依舊可以訪問,本地終端訪問被拒絕了

?5.4.3.4?匹配瀏覽器類型

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     http#acl web_host hdr_dom(host) www.loving_eyes.comacl ip_test src 172.25.254.111 192.168.0.0/24#acl bad_ip src 172.25.254.1acl user_agent_black hdr_sub(User-Agent) -i curl wgetuse_backend webserver1 if ip_testdefault_backend webserver2# curl 和 wget命令都不能訪問haproxyhttp-request deny if user_agent_blackbackend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

?測試:

測試機使用curl 和wget都訪問失敗

5.4.3.5?基于文件后綴名實現動靜分離

為了更好的看到效果,我們加一些配置

在RS2上安裝php,并編寫默認測試頁

[root@RS2 ~]# dnf install php -y[root@RS2 ~]# vim /usr/share/nginx/html/index.php<?phpphpinfo();
?>[root@RS2 ~]# systemctl restart nginx.service

haproxy主機上安裝httpd,并修改端口

[root@haproxy ~]# dnf install httpd -y
# 生成默認測試頁
[root@haproxy ~]# echo "歡迎來到關愛的默認頁面" > /var/www/html/index.html# 修改端口(不然服務起不來)
[root@haproxy ~]# vim /etc/httpd/conf/httpd.conf
**********上面內容省略**********listen 8080**********下面內容省略**********# 開啟服務
[root@haproxy ~]# systemctl enable --now httpd

修改haproxy配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     httpacl url_static path_end -i .jpg .png .css .js .htmlacl url_php path_end -i .php# 靜態頁面訪問RS1use_backend webserver1 if url_static# 動態頁面訪問RS2use_backend webserver2 if url_php# 什么都不做訪問默認頁面default_backend defaultserverbackend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3backend defaultserverserver web1 172.25.254.100:8080 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

測試 (在本地瀏覽器訪問效果更明顯):

默認頁面:

靜態頁面:

?動態頁面(太長了,就只截開頭了):

5.4.3.6?匹配訪問路徑實現動靜分離

再加一些配置:

在RS上加一些默認測試頁

# 兩個RS上都要做
[root@RS1 ~]# mkdir /usr/share/nginx/html/api/
[root@RS1 ~]# echo "RS1 - api" > /usr/share/nginx/html/api/index.html
[root@RS1 ~]# mkdir /usr/share/nginx/html/static/
[root@RS1 ~]# echo "RS1 - static" > /usr/share/nginx/html/static/index.html

可以看到,配置沒問題:

修改haproxy配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webclusterbind     *:80mode     httpacl url_static path_end -m sub /static /images /javascriptacl acl_app path_beg -m sub /apiuse_backend webserver1 if url_staticuse_backend webserver2 if acl_appdefault_backend defaultserverbackend webserver1server web1 172.25.254.10:80 check inter 3s fall 3 rise 3backend webserver2server web2 172.25.254.20:80 check inter 3s fall 3 rise 3backend defaultserverserver web1 172.25.254.100:8080 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

測試:

5.5 自定義HAProxy 錯掉誤界面

5.5.1 基于自定義的錯誤頁面文件

將之前做的ACL注釋(或者刪掉)掉,保證一個干凈的實驗環境:

?將RS2的php頁面刪除,因為php頁面訪問優先級更高,會影響后面的測試效果

[root@RS2 ~]# rm -fr /usr/share/nginx/html/index.php

先查看haproxy的幾個狀態碼頁面放在哪

[root@haproxy ~]# rpm -qa | grep haproxy[root@haproxy ~]# rpm -ql haproxy-2.4.17-3.el9.x86_64 | grep http$

創建一個目錄存放我們自己的狀態碼頁面

[root@haproxy ~]# mkdir /etc/haproxy/errorpage/
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.httpHTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8
<html><body><h1>真是肯尼迪開敞篷車</h1>
真令人摸不著頭腦(bushi)
</body></html>

修改haproxy配置,在defaultsl那欄加,修改完后重啟服務

# 將503狀態頁設定為我們自己編寫的503狀態頁
errorfile 503 /etc/haproxy/errorpage/503.http

關閉RS上的nginx服務

[root@RS1 ~]# systemctl stop nginx.service
[root@RS2 ~]# systemctl stop nginx.service

在瀏覽器測試結果:

5.5.2 基于http重定向錯誤頁面

將之前的配置注釋掉,添加下面這行配置

# 如果頁面處于503狀態,將頁面重定向到百度首頁
errorloc 503 https://www.baidu.com[root@haproxy ~]# systemctl restart haproxy.service

?刷新我們剛才的自定義503頁面,重定向到百度:

重新啟動RS上的nginx,重新訪問haproxy,恢復正常:

5.6 HAProxy 四層負載

針對除HTTP以外的TCP協議應用服務訪問的應用場景

MySQL
Redis
Memcache
RabbitMQ

?四層負載示例(對MySQL進行四層負載)

(1)RS安裝MySQL并編輯配置文件(兩個RS都做)

[root@RS1 ~]# dnf install mariadb-server -y
[root@RS1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=10 # 添加server-id,方便后續看測試效果# 開啟服務
[root@RS1 ~]# systemctl start mariadb.service

查看一下安裝結果:

(2)對RS上的數據庫進行授權

#授權liao用戶能在所有的客戶端(包括本地和遠程)對所有庫的所有表使用所有的功能(增刪改查等)
# -e 表示直接執行這條命令; identified by 表示該用戶的認證密碼為‘liao’[root@RS1 ~]# mysql -e "grant all on *.* to liao@'%' identified by 'liao';"
[root@RS2 ~]# mysql -e "grant all on *.* to liao@'%' identified by 'liao';"

?(3)編輯haproxy配置文件,做四層負載

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfglisten sqlclusterbind *:3306mode tcpbalance roundrobinserver db1 172.25.254.10:3306 check inter 3s fall 3server db2 172.25.254.20:3306 check inter 3s fall 3[root@haproxy ~]# systemctl restart haproxy.service

(4)測試機訪問

挑一臺能跟haproxy主機訪問的主機做測試機,安裝MySQL進行測試

[root@webservera ~]# dnf install mariadb-server -y[root@webservera ~]# mysql -uliao -pliao -h172.25.254.100 -e "select @@server_id"

5.7 HAProxy https 實現

haproxy可以實現https的證書安全,從用戶到haproxyhttps,haproxy到后端服務器用http通信,但基于性能考慮,生產中證書都是在后端服務器比如nginx上實現

5.7.1 證書制作

# 查看selinux狀態(記得關閉selinux)
[root@haproxy ~]# getenforce
Disabled# 建立目錄存放證書
[root@haproxy ~]# mkdir /etc/haproxy/certs/# 制作證書
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/liao.key -x509 -days 365 -out /etc/haproxy/certs/liao.crt

?將證書和密鑰存放到一個文件(liao.pem)里

5.7.2 將證書導入haproxy配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend webcluster-80bind     *:80mode     httpbalance roundrobinredirect scheme https if !{ ssl_fc }use_backend webserverfrontend webcluster-443bind     *:443 ssl crt /etc/haproxy/certs/liao.pemmode     httpbalance roundrobinuse_backend webserverbackend webserverserver web1 172.25.254.10:80 check inter 3s fall 3 rise 3server web2 172.25.254.20:80 check inter 3s fall 3 rise 3[root@haproxy ~]# systemctl restart haproxy.service

?測試:瀏覽器訪問haproxy(不指定端口)

刷新網頁后訪問RS2

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93132.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93132.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93132.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【集合】JDK1.8 HashMap 底層數據結構深度解析

一、核心數據結構&#xff1a;為什么是 "數組 鏈表 紅黑樹"&#xff1f;?HashMap 的底層設計本質是用空間換時間&#xff0c;通過哈希表的快速定位特性&#xff0c;結合鏈表和紅黑樹處理沖突&#xff0c;平衡查詢與插入效率。?1.1 基礎容器&#xff1a;哈希桶數組…

【element-ui】HTML引入本地文件出現font找不到/fonts/element-icons.woff

文章目錄目錄結構問題復現解決辦法目錄結構 |-web|- public|- lib|- ...|- index.htmlindex.html <!DOCTYPE html> <html> <head><meta charset"UTF-8"><!-- import CSS --><link rel"stylesheet" href"./public/…

Windows|CUDA和cuDNN下載和安裝,默認安裝在C盤和不安裝在C盤的兩種方法

本篇文章將詳細介紹在Windows操作系統中配置CUDA和cuDNN的步驟。通過本教程&#xff0c;您將能夠輕松完成CUDA和cuDNN的安裝、環境變量配置以及與深度學習框架&#xff08;如TensorFlow和PyTorch&#xff09;兼容性測試&#xff0c;從而為您的深度學習項目提供強大的硬件支持。…

Vue 項目動態接口獲取翻譯數據實現方案(前端處理語言翻譯 vue-i18n)

在大型多語言項目中&#xff0c;將翻譯數據硬編碼在項目中往往不夠靈活。通過接口動態獲取翻譯數據&#xff0c;并結合本地緩存提升性能&#xff0c;是更優的國際化實現方式。本文將詳細介紹如何在 Vue 項目中實現這一方案。 方案優勢 靈活性高&#xff1a;翻譯內容更新無需修改…

Mybatis-plus多數據源

適用于多種場景&#xff1a;純粹多庫、 讀寫分離、 一主多從、 混合模式等目前我們就來模擬一個純粹多庫的一個場景&#xff0c;其他場景類似場景說明&#xff1a;我們創建兩個庫&#xff0c;分別為&#xff1a; mybatis_plus&#xff08;以前的庫不動&#xff09;與my…

廣東省省考備考(第五十六天7.25)——常識:科技常識(聽課后強化訓練)

錯題解析解析解析解析解析解析解析解析解析標記題解析解析今日題目正確率&#xff1a;40%

RabbitMQ簡述

RabbitMQ簡述 RabbitMQ 是一個開源的 消息代理&#xff08;Message Broker&#xff09; 軟件&#xff0c;實現了 高級消息隊列協議&#xff08;AMQP&#xff09;&#xff0c;用于在分布式系統中存儲、轉發消息&#xff0c;支持異步通信、解耦服務、負載均衡和消息緩沖。 核心…

skywalking應用性能監控

1.skywalking描述 官方文檔 SkyWalking 是一個開源的可觀測性平臺&#xff0c;用于收集、分析、匯總和可視化來自服務及云原生基礎設施的數據。SkyWalking 為維護分布式系統的清晰視圖提供了簡便的方法&#xff0c;即使是在跨云環境中也能做到。它是一款專為云原生、基于容器的…

如何徹底清除服務器上的惡意軟件與后門

清除服務器上的惡意軟件與后門 是確保服務器安全的關鍵步驟。惡意軟件和后門可能導致數據泄露、性能下降&#xff0c;甚至服務器被攻擊者完全控制。以下是徹底清除惡意軟件與后門的詳細指南&#xff0c;包括 檢測、清理、修復與預防 的步驟。1. 徹底清除惡意軟件與后門的步驟1.…

Linux和Windows基于V4L2和TCP的QT監控

最近工作需要用QT做一個網絡攝像頭測試&#xff0c;簡單記錄&#xff1a;服務端&#xff0c;主機配置為Ubuntu&#xff0c;通過端口12345采集傳輸MJPEG格式圖片windows客戶端&#xff0c;QT Creator通過ip地址連接訪問提前準備服務端需要安裝QT5sudo apt-get install qt5-defau…

yolo格式

labelimg中的格式yolo格式id 框中心點X對于總圖片的比例 框中心點Y對于總圖片的比例 框X總長度對于總圖片的比例 框Y總長度對于總圖片的比例

Day 8-zhou R包批量安裝小補充!!!

BiocManager::install(c(“S4Vectors”, “BiocGenerics”)) 以下是使用BiocManager安裝S4Vectors和BiocGenerics包的詳細步驟。這些步驟基于最新的Bioconductor和R版本&#xff08;R 4.5&#xff09;。 安裝步驟安裝BiocManager 如果你還沒有安裝BiocManager&#xff0c;可以使…

電商項目_核心業務_數據歸檔

無論采用哪種存儲系統&#xff0c;數據查詢的耗時取決于兩個因素查找的時間復雜度數據總量查找的時間復雜度又取決于查找算法數據存儲結構以Mysql存儲的訂單數據為例&#xff0c;隨著業務的發展&#xff0c;數據量越來越大&#xff0c;對一些歷史歸檔數據的查詢&#xff0c;如果…

第十講:stack、queue、priority_queue以及deque

目錄 1、stack 1.1、stack的使用 1.2、stack的OJ題 1.2.1、最小棧 1.2.2、棧的壓入彈出序列 1.2.3、逆波蘭表達式求值 1.3、stack的模擬實現 2、queue 2.1、queue的使用 2.2、queue的OJ題 2.2.1、二叉樹的層序遍歷 2.3、queue的模擬實現 3、priority_queue 3.1、…

如何思考一個動態規劃問題需要幾個狀態?

如何思考一個動態規劃問題需要幾個狀態&#xff1f;第一步&#xff1a;思考 角色第二步&#xff1a;考慮 過去的影響第三步&#xff1a;畫出狀態轉移圖第四步&#xff1a;寫出狀態轉移方程第五步&#xff1a;驗證是否能覆蓋所有路徑 邊界幾個常見題目總結&#xff1a;第一步&a…

【每天一個知識點】生成對抗聚類(Generative Adversarial Clustering, GAC)

&#x1f4d8; 生成對抗聚類&#xff08;Generative Adversarial Clustering, GAC&#xff09; 一、研究背景與動機 聚類是無監督學習中的核心任務。傳統方法如 K-means、GMM、DBSCAN 等難以適應高維、非線性、復雜結構數據。 生成對抗聚類&#xff08;GAC&#xff09; 融合…

Qt 窗口 工具欄QToolBar、狀態欄StatusBar

每日激勵&#xff1a;“不設限和自我肯定的心態&#xff1a;I can do all things。 — Stephen Curry” 緒論?&#xff1a; 一段時間沒有更新&#xff0c;這段時間一直在忙各種事情&#xff0c;后續將再次上路持續更新C相關知識 本章將繼續前面的QT篇章&#xff0c;本章主要講…

FFmpeg——參數詳解

FFmpeg參數詳解一、基本命令結構1.1、查詢參數1.1.1、version1.1.2、buildconf1.1.3、devices1.1.4、formats1.1.5、muxers1.1.6、demuxers1.1.7、codecs1.1.8、decoders1.1.9、encoders1.1.10、bsfs1.1.11、protocols1.1.12、filters1.1.13、pix_fmts1.1.14、layouts1.1.15、s…

流媒體傳輸:RTSP傳輸詳解(包含RTP,RTCP,RTSP詳解)

一、什么是 RTSP?協議 1.1 RTSP 協議簡介? RTSP&#xff0c;全稱實時流傳輸協議&#xff08;Real Time Streaming Protocol&#xff09;&#xff0c;是一種位于應用層的網絡協議。它主要用于在流媒體系統中控制實時數據&#xff08;如音頻、視頻等&#xff09;的傳輸&#…

Python學習-----1.認識Python

目錄 前言 1.關于Python博客前期的內容 2.計算機基礎概念 2.1.什么是計算機? 2.2.什么是編程&#xff1f; 2.3.編程語言有哪些&#xff1f; 3.Python背景知識 3.1.Python是怎么來的&#xff1f; 3.2.Python都可以用來干什么&#xff1f; 3.3.Python的優缺點 3.4.Py…