三、Haproxy的排程演算法
System OS: CentOS Linux release 7.8.2003 (Core) 核心:3.10.0-1127.el7.x86_64 web01: node1 10.0.0.201 nginx web02: node2 10.0.0.202 nginx haproxy: node4 192.168.32.204 外網 node4 10.0.0.204 內網 客戶機: node3 192.168.32.203
實驗環境的部署見《
https://www.cnblogs.com/yaokaka/
yum install -y socat #Socat 是 Linux 下的一個多功能的網路工具,名字來由是Socket CAT,Socat 的主要特點就是在兩個資料流之間建立通道,且支援眾多協議和連結方式。如 IP、TCP、 UDP、IPv6、Socket檔案等。 #檢視haproxy的資訊echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock # echo "get weight web_port/web01" | socat stdio /var/lib/haproxy/haproxy.sock 1 (initial 1) echo "set weight web_port/web01 2" | socat stdio /var/lib/haproxy/haproxy.sock Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
1、靜態演算法
靜態演算法:按照事先定義好的規則輪詢公平排程,不關心後端伺服器的當前負載、連結數和相應速度等,且無法實 時修改權重,只能靠重啟HAProxy生效。
static-rr
static-rr:基於權重的輪詢排程,不支援權重的執行時調整及後端伺服器慢啟動,其後端主機數量沒有限制
listen web_port bind 192.168.32.204:80 mode http log global balance static-rr server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80weight 2 check inter 3000 fall 2 rise 5
重啟haproxy
systemctl restart haproxy
測試
[root@node3 ~]# curl 192.168.32.204 web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204 web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204 web01 10.0.0.201 #按照權重來分配後端伺服器
first:根據伺服器在列表中的位置,自上而下進行排程,但是其只會當第一臺伺服器的連線數達到上限,新請求才 會分配給下一臺服務,因此會忽略伺服器的權重設定。
listen web_port bind 192.168.32.204:80 mode http log global balance first server web01 10.0.0.201:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
重啟haproxy
systemctl restart haproxy
測試
[root@node3 ~]# while true;do curl 192.168.32.204 ;sleep 0.1;done web01 10.0.0.201 web01 10.0.0.201 web02 10.0.0.202 web01 10.0.0.201 web01 10.0.0.201 web01 10.0.0.201 web01 10.0.0.201 web02 10.0.0.202 web01 10.0.0.201 #只有在web01伺服器連線數達到上限值後,才會把請求分配給web02
動態演算法:基於後端伺服器 狀態進行排程適當調整,比如優先排程至當前負載較低的伺服器,且權重可以在 haproxy執行時動態調整無需重啟。
直接reload即可
systemctl reload haproxy
roundrobin:基於權重的輪詢動態排程演算法,支援權重的執行時調整,不完全等於lvs中的rr輪訓模式,HAProxy中的roundrobin支援慢啟動(新加的伺服器會逐漸增加轉發數),其每個後端backend中最多支援4095個real server,roundrobin為預設排程演算法,且支援對real server權重動態調整。
listen web_port bind 192.168.32.204:80 mode http log global balance roundrobin server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
reload haproxy
systemctl reload haproxy
測試
[root@node3 ~]# while true;do curl 192.168.32.204;sleep 0.5 ;done web01 10.0.0.201 web02 10.0.0.202 web02 10.0.0.202 web01 10.0.0.201 web01 10.0.0.201 web02 10.0.0.202 web02 10.0.0.202 web01 10.0.0.201 web02 10.0.0.202 #按照權重來分配後端伺服器
動態修改權重
#把web01的權重改為3 #把web02的權重改為1 [root@node4 haproxy]# echo "set weight web_port/web01 3" | socat stdio /var/lib/haproxy/haproxy.sock [root@node4 haproxy]# echo "set weight web_port/web02 1" | socat stdio /var/lib/haproxy/haproxy.sock [root@node4 haproxy]# echo "get weight web_port/web01" | socat stdio /var/lib/haproxy/haproxy.sock 3 (initial 1) [root@node4 haproxy]# echo "get weight web_port/web02" | socat stdio /var/lib/haproxy/haproxy.sock 1 (initial 2)
測試
[root@node3 ~]# while true;do curl 192.168.32.204;sleep 0.5 ;done web01 10.0.0.201 web01 10.0.0.201 web02 10.0.0.202 web01 10.0.0.201 web01 10.0.0.201 web01 10.0.0.201 web02 10.0.0.202 web01 10.0.0.201 web01 10.0.0.201 #按照web01:web02=3:1來分配
leastconn
listen web_port bind 192.168.32.204:80 mode http log global balance leastconn server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
reload haproxy
systemctl reload haproxy
其它部分演算法即可作為靜態演算法,又可以通過選項成為動態演算法
3.1 source
源地址hash,基於使用者源地址hash並將請求轉發到後端伺服器,預設為靜態即取模方式,但是可以通過hash-type 支援的選項更改,後續同一個源地址請求將被轉發至同一個後端web伺服器,比較適用於session保持/快取業務等 場景。 源地址有兩種轉發客戶端請求到後端伺服器的伺服器選取計算方式,分別是取模法(靜態)和一致性hash(動態)
3.1.1 map-base取模法(靜態)
map-based:取模法,基於伺服器總權重的hash陣列取模,該hash是靜態的即不支援線上調整權重,不支援慢啟 動,其對後端伺服器排程均衡,缺點是當伺服器的總權重發生變化時,即有伺服器上線或下線,都會因權重發生變化而 導致排程結果整體改變。 所謂取模運算,就是計算兩個數相除之後的餘數,10%7=3, 7%4=3,基於權重取模:(2^32-1)%(1+1+2)
listen web_port bind 192.168.32.204:80 mode http log global balance source server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
3.1.2 :一致性hash(動態)
listen web_port bind 192.168.32.204:80 mode http log global balance source hash-type consistent server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
測試
[root@node3 ~]# curl 192.168.32.204/index.html web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204/index.html web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204/index.html web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204/index.html web02 10.0.0.202 #同一個源地址請求將被轉發至同一個後端web伺服器
3.2 uri
基於對使用者請求的uri做hash並將請求轉發到後端指定伺服器,也可以通過map-based和consistent定義使用取模
http://example.org/absolute/URI/with/absolute/path/to/resource.txt #URI/URL ftp://example.org/resource.txt #URI/URL /relative/URI/with/absolute/path/to/resource.txt #URI
listen web_port bind 192.168.32.204:80 mode http log global balance uri server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 2 check inter 3000 fall 2 rise 5
listen web_port bind 192.168.32.204:80 mode http log global balance uri hash-type consistent server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
測試
在web01和web02在建立一個index1.html web01 echo 'test01 10.0.0.201' > /usr/share/nginx/html/index1.html web02 echo 'test02 10.0.0.202' > /usr/share/nginx/html/index1.html [root@node3 ~]# curl 10.0.0.201/index.html web01 10.0.0.201 [root@node3 ~]# curl 10.0.0.201/index1.html test01 10.0.0.201
訪問haproxy檢視結果
[root@node3 ~]# curl 192.168.32.204/index.html web02 10.0.0.202 [root@node3 ~]# curl 192.168.32.204/index1.html test01 10.0.0.201 再找一臺客戶機測試 root@ubuntu-node1:~# curl 192.168.32.204/index.html web02 10.0.0.202 root@ubuntu-node1:~# curl 192.168.32.204/index1.html test01 10.0.0.201 #訪問不同的uri,確認可以將使用者同樣的請求轉發至相同的伺服器
url_param對使用者請求的url中的 params 部分中的引數name作hash計算,並由伺服器總權重相除以後派發至某挑 出的伺服器;通常用於追蹤使用者,以確保來自同一個使用者的請求始終發往同一個real server
假設url = http://www.kingseal.com/foo/bar/index.php?k1=v1&k2=v2 則: host = "www.kingseal.com" url_param = "k1=v1&k2=v2"
listen web_port bind 192.168.32.204:80 mode http log global balance url_param k1,k2 server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
listen web_port bind 192.168.32.204:80 mode http log global balance url_param k1,k2 hash-type consistent server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
測試
客戶機訪問一下資訊 curl http://192.168.32.204/index.html?k1=NAME #單個引數訪問 curl http://192.168.32.204/index.html?k2=AGE curl http://192.168.32.204/index.html?k2=AGE&&k1=NAME #多個引數訪問
針對使用者每個http頭部(header)請求中的指定資訊做hash,此處由 name 指定的http首部將會被取出並做hash計 算,然後由伺服器總權重相除以後派發至某挑出的伺服器,假如無有效的值,則會使用預設的輪詢排程。
3.4.1 hdr取模法配置(靜態)
listen web_port bind 192.168.32.204:80 mode http log global balance hdr(User-Agent) server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
listen web_port bind 192.168.32.204:80 mode http log global balance hdr(User-Agent) hash-type consistent server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
測試
[root@node3 ~]# curl http://192.168.32.204/index.html web01 10.0.0.201 [root@node3 ~]# curl http://192.168.32.204/index.html web01 10.0.0.201 [root@node3 ~]# curl http://192.168.32.204/index.html web01 10.0.0.201 [root@node3 ~]# curl http://192.168.32.204/index.html web01 10.0.0.201 #根據http head中瀏覽器的型別把資料轉發到同一個後端伺服器
rdp-cookie對遠windows程桌面的負載,使用cookie保持會話
3.5.1 rdp-cookie取模法配置(靜態)
listen RDP bind 192.168.32.204:3389 balance rdp-cookie mode tcp server rdp0 10.0.0.201:3389 check fall 3 rise 5 inter 2000 weight 1
listen RDP bind 192.168.32.204:3389 balance rdp-cookie mode tcp hash-type consistent server rdp0 10.0.0.201:3389 check fall 3 rise 5 inter 2000 weight 1
#必須開啟ip轉發功能 cat >> /etc/sysctl.conf <<EOF net.ipv4.ip_forward = 1 EOF sysctl -p iptables -t nat -A PREROUTING -d 192.168.32.204 -p tcp --dport 3389 -j DNAT --todestination 10.0.0.201:3389 iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -j SNAT --to-source 192.168.32.204
在1.9版本開始增加一個叫做random的負載平衡演算法,其基於一個隨機數作為一致性hash的key,隨機負載平衡對 於大型伺服器場或經常新增或刪除伺服器非常有用,因為它可以避免在這種情況下由roundrobin或leastconn導致 的錘擊效應。
random配置
listen web_port bind 192.168.32.204:80 mode http log global balance random server web01 10.0.0.201:80 weight 1 check inter 3000 fall 2 rise 5 server web02 10.0.0.202:80 weight 1 check inter 3000 fall 2 rise 5
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 rdp-cookie-------->tcp
first #使用較少 static-rr #做了session共享的web叢集 roundrobin #預設 random leastconn #資料庫 source #基於客戶端公網IP的會話保持 Uri--------------->http #快取伺服器,CDN服務商,藍汛、百度、阿里雲、騰訊 url_param--------->http hdr #基於客戶端請求報文頭部做下一步處理 rdp-cookie #很少使用