HAProxy 调度算法
在LVS关于负载均衡的十种调度算法中,分为静态调度算法和动态调度算法两种,静态调度是指无视后端服务负载情况执行调度命令,而动态调度算法是根据后端的动态变化负载权重去执行调度命令。这种类似的用法在haproxy中也存在。
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,该参数可以配置在listen或backend选项中。
HAProxy的调度算法分为静态和动态调度算法,但是有些算法可以根据参数在静态和动态算法中相互转换。
官方文档:http://cbonte.github.io/haproxy-dconv/2.4/configuration.html#4-balance
静态算法:
- 按照事先定义好的规则轮询进行调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时动态修改权重(只能为0和1,不支持其它值)或者修改后不生效,如果需要修改只能靠重启HAProxy生效。
Socat 工具 - 有利于实现脚本自动化管理
- 对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等
案例:利用工具socat 对haproxy服务器进行管理 - 不用重启服务能立即生效,注意只针对单进程有效
http://haproxy-server:9999/haproxy-status 状态页面也可以查看
#同一主机上两个程序,例如客户端程序与服务端程序,可通过socket进行通讯 haproxy自带socket
[root@haproxy ~]#cat /etc/haproxy/haproxy.cfg
global
maxconn 100000
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin --> 该文件实现socket和haproxy之间的通讯
....
[root@haproxy ~]#file /var/lib/haproxy/haproxy.sock
/var/lib/haproxy/haproxy.sock: socket
#安装socat
[root@haproxy ~]#apt -y install socat
#查看帮助
[root@haproxy ~]#socat -h
#查看haproxy.sock可接受那些指令
[root@haproxy ~]#echo "help" | socat stdio /var/lib/haproxy/haproxy.sock
The following commands are valid at this level:
abort ssl ca-file <cafile> : abort a transaction for a CA file
abort ssl cert <certfile> : abort a transaction for a certificate file
abort ssl crl-file <crlfile> : abort a transaction for a CRL file
add acl [@<ver>] <acl> <pattern> : add an acl entry
add map [@<ver>] <map> <key> <val> : add a map entry (payload supported instead of key/val)
add server <bk>/<srv> : create a new server
add ssl ca-file <cafile> <payload> : add a certificate into the CA file
add ssl crt-list <list> <cert> [opts]* : add to crt-list file <list> a line <cert> or a payload
clear acl [@<ver>] <acl> : clear the contents of this acl
clear counters [all] : clear max statistics counters (or all counters)
clear map [@<ver>] <map> : clear the contents of this map
clear table <table> [<filter>]* : remove an entry from a table (filter: data/key)
commit acl @<ver> <acl> : commit the ACL at this version
commit map @<ver> <map> : commit the map at this version
commit ssl ca-file <cafile> : commit a CA file
commit ssl cert <certfile> : commit a certificate file
commit ssl crl-file <crlfile> : commit a CRL file
debug dev hash [msg] : return msg hashed if anon is set
del acl <acl> [<key>|#<ref>] : delete acl entries matching <key>
del map <map> [<key>|#<ref>] : delete map entries matching <key>
del server <bk>/<srv> : remove a dynamically added server
del ssl ca-file <cafile> : delete an unused CA file
del ssl cert <certfile> : delete an unused certificate file
del ssl crl-file <crlfile> : delete an unused CRL file
del ssl crt-list <list> <cert[:line]> : delete a line <cert> from crt-list file <list>
disable agent : disable agent checks
disable dynamic-cookie backend <bk> : disable dynamic cookies on a specific backend
disable frontend <frontend> : temporarily disable specific frontend
disable health : disable health checks
disable server (DEPRECATED) : disable a server for maintenance (use 'set server' instead)
enable agent : enable agent checks
enable dynamic-cookie backend <bk> : enable dynamic cookies on a specific backend
enable frontend <frontend> : re-enable specific frontend
enable health : enable health checks
enable server (DEPRECATED) : enable a disabled server (use 'set server' instead)
get acl <acl> <value> : report the patterns matching a sample for an ACL
get map <acl> <value> : report the keys and values matching a sample for a map
get var <name> : retrieve contents of a process-wide variable
get weight <bk>/<srv> : report a server's current weight
new ssl ca-file <cafile> : create a new CA file to be used in a crt-list
new ssl cert <certfile> : create a new certificate file to be used in a crt-list or a directory
new ssl crlfile <crlfile> : create a new CRL file to be used in a crt-list
operator : lower the level of the current CLI session to operator
prepare acl <acl> : prepare a new version for atomic ACL replacement
prepare map <acl> : prepare a new version for atomic map replacement
set anon <setting> [value] : change the anonymized mode setting
set anon global-key <value> : change the global anonymizing key
set dynamic-cookie-key backend <bk> <k> : change a backend secret key for dynamic cookies
set map <map> [<key>|#<ref>] <value> : modify a map entry
set maxconn frontend <frontend> <value> : change a frontend's maxconn setting
set maxconn global <value> : change the per-process maxconn setting
set maxconn server <bk>/<srv> : change a server's maxconn setting
set profiling <what> {auto|on|off} : enable/disable resource profiling (tasks,memory)
set rate-limit <setting> <value> : change a rate limiting value
set server <bk>/<srv> [opts] : change a server's state, weight, address or ssl
set severity-output [none|number|string]: set presence of severity level in feedback information
set ssl ca-file <cafile> <payload> : replace a CA file
set ssl cert <certfile> <payload> : replace a certificate file
set ssl crl-file <crlfile> <payload> : replace a CRL file
set ssl ocsp-response <resp|payload> : update a certificate's OCSP Response from a base64-encode DER
set ssl tls-key [id|file] <key> : set the next TLS key for the <id> or <file> listener to <key>
set table <table> key <k> [data.* <v>]* : update or create a table entry's data
set timeout [cli] <delay> : change a timeout setting
set weight <bk>/<srv> (DEPRECATED) : change a server's weight (use 'set server' instead)
show acl [@<ver>] <acl>] : report available acls or dump an acl's contents
show activity [-1|0|thread_num] : show per-thread activity stats (for support/developers)
show anon : display the current state of anonymized mode
show backend : list backends in the current running config
show cache : show cache status
show cli level : display the level of the current CLI session
show cli sockets : dump list of cli sockets
show env [var] : dump environment variables known to the process
show errors [<px>] [request|response] : report last request and/or response errors for each proxy
show events [<sink>] [-w] [-n] : show event sink state
show fd [num] : dump list of file descriptors in use or a specific one
show info [desc|json|typed|float]* : report information about the running process
show libs : show loaded object files and libraries
show map [@ver] [map] : report available maps or dump a map's contents
show peers [dict|-] [section] : dump some information about all the peers or this peers section
show pools [by*] [match <pfx>] [nb] : report information about the memory pools usage
show profiling [<what>|<#lines>|<opts>]*: show profiling state (all,status,tasks,memory)
show resolvers [id] : dumps counters from all resolvers section and associated name servers
show schema json : report schema used for stats
show servers conn [<backend>] : dump server connections status (all or for a single backend)
show servers state [<backend>] : dump volatile server information (all or for a single backend)
show sess [id] : report the list of current sessions or dump this exact session
show ssl ca-file [<cafile>[:<index>]] : display the SSL CA files used in memory, or the details of a <cafile>, or a single certificate of index <index> of a CA file <cafile>
show ssl cert [<certfile>] : display the SSL certificates used in memory, or the details of a file
show ssl crl-file [<crlfile[:<index>>]] : display the SSL CRL files used in memory, or the details of a <crlfile>, or a single CRL of index <index> of CRL file <crlfile>
show ssl crt-list [-n] [<list>] : show the list of crt-lists or the content of a crt-list file <list>
show ssl ocsp-response [id] : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response
show ssl providers : show loaded SSL providers
show startup-logs : report logs emitted during HAProxy startup
show stat [desc|json|no-maint|typed|up]*: report counters for each proxy and server
show table <table> [<filter>]* : report table usage stats or dump this table's contents (filter: data/key)
show tasks : show running tasks
show threads : show some threads debugging information
show tls-keys [id|*] : show tls keys references or dump tls ticket keys when id specified
show trace [<module>] : show live tracing state
show version : show version of the current process
shutdown frontend <frontend> : stop a specific frontend
shutdown session [id] : kill a specific session
shutdown sessions server <bk>/<srv> : kill sessions on a server
trace [<module>|0] [cmd [args...]] : manage live tracing (empty to list, 0 to stop all)
user : lower the level of the current CLI session to user
help [<command>] : list matching or all commands
prompt : toggle interactive mode with prompt
quit : disconnect
#查看线程
[root@haproxy ~]#echo "show threads" | socat stdio /var/lib/haproxy/haproxy.sock
Thread 1 : id=0x7fe6932ba0c0 act=0 glob=0 wq=0 rq=0 tl=0 tlsz=0 rqsz=0
1/1 stuck=0 prof=0 harmless=1 wantrdv=0
cpu_ns: poll=27025059 now=27106301 diff=81242
curr_task=0
Thread 2 : id=0x7fe6932ae640 act=0 glob=0 wq=1 rq=0 tl=0 tlsz=0 rqsz=0
1/2 stuck=0 prof=0 harmless=1 wantrdv=0
cpu_ns: poll=5841499886 now=5841806929 diff=307043
curr_task=0
* Thread 3 : id=0x7fe690ad3640 act=1 glob=0 wq=1 rq=0 tl=0 tlsz=0 rqsz=0
1/3 stuck=0 prof=0 harmless=0 wantrdv=0
cpu_ns: poll=2687436766 now=2687675923 diff=239157
curr_task=0x7fe67c034830 (task) calls=2 last=0
fct=0x55887b9ce170(task_run_applet) ctx=0x7fe67c034e70(<CLI>)
strm=0x7fe67c034440,8 src=unix fe=GLOBAL be=GLOBAL dst=<CLI>
txn=(nil),0 txn.req=-,0 txn.rsp=-,0
rqf=c08002 rqa=0 rpf=80008000 rpa=0
scf=0x7fe67c026800,EST,0 scb=0x7fe67c0348e0,EST,1
af=(nil),0 sab=0x7fe67c034e70,11
cof=0x7fe67c034bd0,300:PASS(0x7fe67c026c20)/RAW((nil))/unix_stream(25)
cob=(nil),0:NONE((nil))/NONE((nil))/NONE(-1)
Thread 4 : id=0x7fe68bfff640 act=0 glob=0 wq=1 rq=0 tl=0 tlsz=0 rqsz=0
1/4 stuck=0 prof=0 harmless=1 wantrdv=0
cpu_ns: poll=1573141326 now=1573420254 diff=278928
curr_task=0
#查看正在运行的后端服务
[root@haproxy ~]#echo "show backend" | socat stdio /var/lib/haproxy/haproxy.sock
# name
stats
www.mooreyxia.net_80
www.mooreyxia.org_servers
#可以用于实现Zabbix监控
[root@haproxy ~]#echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock
Name: HAProxy
Version: 2.7.1-3e4af0e
Release_date: 2022/12/19
Nbthread: 4
Nbproc: 1
Process_num: 1
Pid: 1257
Uptime: 0d 4h10m05s
Uptime_sec: 15005
Memmax_MB: 0
PoolAlloc_MB: 0
PoolUsed_MB: 0
PoolFailed: 0
Ulimit-n: 200041
Maxsock: 200041
Maxconn: 100000
Hard_maxconn: 100000
CurrConns: 0
CumConns: 17492
CumReq: 12
MaxSslConns: 0
CurrSslConns: 0
CumSslConns: 0
Maxpipes: 0
PipesUsed: 0
PipesFree: 0
ConnRate: 0
ConnRateLimit: 0
MaxConnRate: 3
SessRate: 0
SessRateLimit: 0
MaxSessRate: 3
SslRate: 0
SslRateLimit: 0
MaxSslRate: 0
SslFrontendKeyRate: 0
SslFrontendMaxKeyRate: 0
SslFrontendSessionReuse_pct: 0
SslBackendKeyRate: 0
SslBackendMaxKeyRate: 0
SslCacheLookups: 0
SslCacheMisses: 0
CompressBpsIn: 0
CompressBpsOut: 0
CompressBpsRateLim: 0
ZlibMemUsage: 0
MaxZlibMemUsage: 0
Tasks: 23
Run_queue: 0
Idle_pct: 100
node: haproxy
Stopping: 0
Jobs: 6
Unstoppable Jobs: 1
Listeners: 5
ActivePeers: 0
ConnectedPeers: 0
DroppedLogs: 0
BusyPolling: 0
FailedResolutions: 0
TotalBytesOut: 78033
TotalSplicdedBytesOut: 0
BytesOutRate: 0
DebugCommandsIssued: 0
CumRecvLogs: 0
Build info: 2.7.1-3e4af0e
Memmax_bytes: 0
PoolAlloc_bytes: 252168
PoolUsed_bytes: 252168
Start_time_sec: 1673947932
Tainted: 0
#获取当前连接数
[root@haproxy ~]#echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock |awk '/CurrConns/{print $2}'
0
#查看当前服务器的状态值
[root@haproxy ~]#echo "show servers state" | socat stdio /var/lib/haproxy/haproxy.sock
1
# 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 www.mooreyxia.net_80 1 web01 10.0.0.204 0 0 1 1 15291 8 2 0 6 0 0 0 - 80 - 0 0 - - 0
3 www.mooreyxia.net_80 2 web02 10.0.0.205 0 0 1 1 15288 7 0 0 7 0 0 0 - 80 - 0 0 - - 0
5 www.mooreyxia.org_servers 1 web01 10.0.0.202 2 0 1 1 15292 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
5 www.mooreyxia.org_servers 2 web02 10.0.0.203 2 0 1 1 15292 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
#获取特定服务器的权重
[root@haproxy ~]#echo "get weight www.mooreyxia.net_80/web02" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
#通过set设置服务器的权重
[root@haproxy ~]#echo "set weight www.mooreyxia.net_80/web02 2" | socat stdio /var/lib/haproxy/haproxy.sock
[root@haproxy ~]#echo "get weight www.mooreyxia.net_80/web02" | socat stdio /var/lib/haproxy/haproxy.sock
2 (initial 1)
#下线端服务器
[root@haproxy ~]#echo "disable server www.mooreyxia.org_servers/web01" | socat stdio /var/lib/haproxy/haproxy.sock
#上线后端服务器
[root@haproxy ~]#echo "enable server www.mooreyxia.org_servers/web01" | socat stdio /var/lib/haproxy/haproxy.sock
#新的写法
#相当于disable server
[root@haproxy ~]#echo "set server www.mooreyxia.org_servers/web01 state maint" |socat stdio /var/lib/haproxy/haproxy.sock
#相当于enable server
[root@haproxy ~]#echo "set server www.mooreyxia.org_servers/web01 state ready" |socat stdio /var/lib/haproxy/haproxy.sock
#drain - active or backup SOFT STOPPED for maintenance 相当于nginx中的平滑下线,已建立连接的用户不会被断开
[root@haproxy ~]#echo "set server www.mooreyxia.org_servers/web01 state drain" |socat stdio /var/lib/haproxy/haproxy.sock
案例:上线和下线后端服务器脚本
#查看配置的服务名
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 check inter 3000 fall 3 rise 5
#frontend www.mooreyxia.org
# bind 192.168.10.200:80
# use_backend www.mooreyxia.org_servers
#backend www.mooreyxia.org_servers
# server web01 10.0.0.202:80 check inter 3000 fall 3 rise 5
# server web02 10.0.0.203:80 check inter 3000 fall 3 rise 5
#脚本
[root@haproxy ~]#vim haproxy_host_up_down.sh
[root@haproxy ~]#cat haproxy_host_up_down.sh
#!/bin/bash
#
#********************************************************************
#Author: mooreyxia
#Date: 2023-01-17
#FileName: haproxy_host_up_down.sh
#Description: The test script
#Copyright (C): 2023 All rights reserved
#********************************************************************
case $1 in
up)
echo "enable server www.mooreyxia.org/$2" | socat stdio /var/lib/haproxy/haproxy.sock
[ $? -eq 0 ] && echo "$2 is up"
;;
down)
echo "disable server www.mooreyxia.org/$2" | socat stdio /var/lib/haproxy/haproxy.sock
[ $? -eq 0 ] && echo "$2 is down"
;;
*)
echo "Usage: `basename $0` up|down IP"
;;
esac
[root@haproxy ~]#chmod +x haproxy_host_up_down.sh
#下线202 - 上线执行up即可
[root@haproxy ~]#./haproxy_host_up_down.sh down 10.0.0.202
10.0.0.202 is down
案例:实现容器服务的上线和下线脚本 - 针对 docker-nginx 服务做平滑升级
WEB_SERVERS="
10.0.0.101
10.0.0.102
"
for i in $WEB_SERVERS;do
echo "set server www.mooreyxia.org_nginx/$i state maint" | socat stdio /var/lib/haproxy/haproxy.sock
ssh $i docker rm -f nginx
ssh $i "echo DOCKER $i WEBSITE $1 > /data/www/index.html"
ssh $i docker run -d -p 80:80 -v /data/www:/usr/share/nginx/html --name nginx nginx
sleep 10
echo "set server www.mooreyxia.org_nginx/$i state ready" | socat stdio /var/lib/haproxy/haproxy.sock
done
static-rr 算法
- static-rr:基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1),不支持其它值及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr
案例:
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance static-rr
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
#不支持运行时利用socat进行权重的动态调整
[root@haproxy ~]#echo "get weight www.mooreyxia.org/10.0.0.202 " |socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 3)
[root@haproxy ~]#echo "get weight www.mooreyxia.org/10.0.0.203 " |socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
#尝试运行时更改权重
[root@haproxy ~]#echo "set weight www.mooreyxia.org/10.0.0.203 4" |socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
first 算法
- first:根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少
- **不支持用socat进行动态修改权重,**可以设置0和1,可以设置其它值但无效
案例:
#设置最大连接数一个,达到连接上线后全部调度访问另一个服务
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance first
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 maxconn 1 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
#占用202
[root@internet ~]#wget --limit-rate 10 http://www.mooreyxia.org/1.txt
--2023-01-18 11:43:06-- http://www.mooreyxia.org/1.txt
Resolving www.mooreyxia.org (www.mooreyxia.org)... 192.168.10.200
Connecting to www.mooreyxia.org (www.mooreyxia.org)|192.168.10.200|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 654506 (639K) [text/plain]
Saving to: ‘1.txt.2’
1.txt.1 0%[ ] 1.28K 10.4 B/s eta 18h 8m ^ ] 1.27K 10.0 B/s eta 18h 8m
#测试访问
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
动态算法
- 动态算法:基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启。
roundrobin 算法
- roundrobin:基于权重的轮询动态调度算法,支持权重的运行时调整,不同于lvs中的rr轮训模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个real server,支持对real server权重动态调整,roundrobin为默认调度算法,此算法使用广泛
案例:
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance roundrobin
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
#尝试运行时更改权重
[root@haproxy ~]#echo "set weight www.mooreyxia.org/10.0.0.203 5" |socat stdio /var/lib/haproxy/haproxy.sock
[root@haproxy ~]#echo "get weight www.mooreyxia.org/10.0.0.203 " |socat stdio /var/lib/haproxy/haproxy.sock
5 (initial 1)
[root@haproxy ~]#echo "get weight www.mooreyxia.org/10.0.0.202 " |socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 3)
#测试
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
leastconn 算法
- leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,相当于LVS的WLC算法。比如:MySQL等场景。
案例:
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance leastconn
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 1 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
random 算法
- 在1.9版本开始增加 random的负载平衡算法,其基于随机数作为一致性hash的key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持weight的动态调整,weight较大的主机有更大概率获取新请求
案例:
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance random
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
可动可静的其他算法
source 算法
- 源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改
- 这个算法一般是在不插入Cookie的TCP模式下使用,也可给不支持会话cookie的客户提供会话粘性,适用于需要session会话保持但不支持cookie和缓存的场景
- 源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
map-base 取模法
- map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重
案例:
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance source
hash-type map-based --> 默认,可不写
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试 - 只要客户端地址是同一地址,调度到服务器的地址固定
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
一致性 hash
- 一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
#算法:
1、key1=hash(source_ip)%(2^32) [0---4294967295]
2、keyA=hash(后端服务器虚拟ip)%(2^32)
3、将key1和keyA都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
#hash环偏斜问题
增加虚拟服务器IP数量,比如:一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权重为2则生成2000的虚拟IP,再进行hash运算,最终在hash环上生成3000个节点,从而解决hash环偏斜问题
一致性hash示意图:
案例:
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance source
hash-type consistent
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试 - 只要客户端地址是同一地址,调度到服务器的地址固定
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
#尝试运行时更改权重
[root@haproxy ~]#echo "set weight www.mooreyxia.org/10.0.0.203 10" |socat stdio /var/lib/haproxy/haproxy.sock
[root@haproxy ~]#echo "get weight www.mooreyxia.org/10.0.0.203 " |socat stdio /var/lib/haproxy/haproxy.sock
10 (initial 1)
uri 算法
- 基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,可设置动态,通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash。
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp【lvs由于是四层负载均衡,拿不到七层的数据,所以做不了七层相关的算法调度】
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
左半部分:/<path>;<params>
整个uri:/<path>;<params>?<query>#<frag>
案例:
#202服务器
[root@web01-mooreyxia ~]#cd /var/www/html/
[root@web01-mooreyxia html]#for i in {1..10};do echo test$i.html on 10.0.0.202 > test$i.html;done
[root@web01-mooreyxia html]#ll
总用量 696
drwxr-xr-x 2 root root 4096 1月 18 13:07 ./
drwxr-xr-x 3 root root 4096 10月 28 16:31 ../
-rw-r--r-- 1 root root 654506 1月 18 11:34 1.txt
-rw-r--r-- 1 root root 36 1月 17 15:13 index.html
-rw-r--r-- 1 root root 612 1月 16 14:42 index.nginx-debian.html
-rw-r--r-- 1 root root 26 1月 18 13:07 test10.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test1.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test2.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test3.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test4.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test5.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test6.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test7.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test8.html
-rw-r--r-- 1 root root 25 1月 18 13:07 test9.html
[root@web01-mooreyxia html]#cat test1.html
test1.html on 10.0.0.202
#203服务器
[root@web02-mooreyxia ~]#cd /var/www/html/
[root@web02-mooreyxia html]#for i in {1..10};do echo test$i.html on 10.0.0.203 > test$i.html;done
[root@web02-mooreyxia html]#ls
index.html index.nginx-debian.html test10.html test1.html test2.html test3.html test4.html test5.html test6.html test7.html test8.html test9.html
[root@web02-mooreyxia html]#cat test3.html
test3.html on 10.0.0.203
#设置uri算法
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance uri
hash-type consistent --> 可设置动态,默认静态
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试 - 用户请求的URI不变则调度向同一服务器
[root@internet ~]#curl http://www.mooreyxia.org/test1.html
test1.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test1.html
test1.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test1.html
test1.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test2.html
test2.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test2.html
test2.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test2.html
test2.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test3.html
test3.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test4.html
test4.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test4.html
test4.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test4.html
test4.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test4.html
test4.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test5.html
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html
test5.html on 10.0.0.202
url_param 算法
- url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法
注意:此算法基于应用层
案例:
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance url_param userid
hash-type consistent --> 可设置动态,默认静态
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试 - key值不变调度至服务器不变
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=1
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=1
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=1
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=2
test5.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=2
test5.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=2
test5.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=2
test5.html on 10.0.0.203
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=3
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=3
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=3
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=4
test5.html on 10.0.0.202
[root@internet ~]#curl http://www.mooreyxia.org/test5.html?userid=4
hdr 算法
- 针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
简单来说就是根据http报文头中的参数做调度运算
案例:针对不同的浏览器进行调度
[root@haproxy ~]#vim /etc/haproxy/conf.d/www.mooreyxia.org.cfg
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance hdr(User-Agent)
hash-type consistent --> 可设置动态,默认静态
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 rise 5
[root@haproxy ~]#systemctl restart haproxy.service
#测试
#查看浏览器版本 - User-Agent: curl/7.61.1
[root@internet ~]#curl http://www.mooreyxia.org/ -Iv
* Trying 192.168.10.200...
* TCP_NODELAY set
* Connected to www.mooreyxia.org (192.168.10.200) port 80 (#0)
> HEAD / HTTP/1.1
> Host: www.mooreyxia.org
> User-Agent: curl/7.61.1
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< server: nginx/1.18.0 (Ubuntu)
server: nginx/1.18.0 (Ubuntu)
< date: Wed, 18 Jan 2023 05:35:17 GMT
date: Wed, 18 Jan 2023 05:35:17 GMT
< content-type: text/html
content-type: text/html
< content-length: 36
content-length: 36
< last-modified: Tue, 17 Jan 2023 07:13:41 GMT
last-modified: Tue, 17 Jan 2023 07:13:41 GMT
< etag: "63c64aa5-24"
etag: "63c64aa5-24"
< accept-ranges: bytes
accept-ranges: bytes
<
* Connection #0 to host www.mooreyxia.org left intact
#访问
[root@internet ~]#curl http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
#更改浏览器版本进行访问
[root@internet ~]#curl -A chrome http://www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl -A chrome http://www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl -A chrome http://www.mooreyxia.org
10.0.0.203 _web02-www.mooreyxia.org
[root@internet ~]#curl -A firefox http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl -A firefox http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
[root@internet ~]#curl -A firefox http://www.mooreyxia.org
10.0.0.202 _web01-www.mooreyxia.org
rdp-cookie 算法
- rdp-cookie对远windows远程桌面的负载,使用cookie保持会话,默认是静态,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash,不常用。
案例:
[root@haproxy ~]#cat /etc/haproxy/conf.d/www.mooreyxia.org.cfg
listen www.mooreyxia.org
balance rdp-cookie
hash-type consistent --> 可设置动态,默认静态
bind 192.168.10.200:80
server 10.0.0.202 10.0.0.202:80 weight 3 check inter 3000 fall 3 rise 5
server 10.0.0.203 10.0.0.203:80 weight 1 check inter 3000 fall 3 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 #可以实现session保持
hdr #基于客户端请求报文头部做下一步处理
rdp-cookie #基于Windows主机,很少使用
我是moore,大家一起加油!!!