HAProxy基础配置-haproxy常见的调度算法

        HAProxy基础配置-haproxy常见的调度算法

                                   作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

  我们知道nginx有四种(rr,ip_hash,uri hash,lastconn)常用的调度算法,LVS有10种(常用的也就3-4种,而且生产环境种使用lvs的场景相对较少,毕竟大多数公司没有淘宝,天猫那个访问量)调度算法,而haproxy的调度算法相对nginx还是比较多的。

  除此之外,haproxy还支持通过socket的方式实现服务器动态的上下限,而nginx和lvs却不支持该功能,接下来我们一起学习一下haproxy吧~

 

 

一.HAProxy调度算法需要使用balance指令来声明

  balance:
    指明对后端服务器的调度算法,配置在listen或backend

1>.编辑haproxy的配置文件(开启socket功能,便于下面测试动态调度算法与通过该socket和haproxy服务在不重启的情况下动态变更配置)

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# ll /yinzhengjie/softwares/haproxy/haproxy.sock 
srw------- 1 root root 0 Jan  3 14:36 /yinzhengjie/softwares/haproxy/haproxy.sock
[[email protected] ~]# 
[[email protected] ~]# ll /yinzhengjie/softwares/haproxy/haproxy.pid 
-rw-r--r-- 1 root root 6 Jan  3 14:36 /yinzhengjie/softwares/haproxy/haproxy.pid
[[email protected] ~]# 

2>.安装socat命令(下面在测试动态修改权重案例时会用到该工具)

[[email protected] ~]# yum -y install socat
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink                                                                                                      | 9.1 kB  00:00:00     
 * base: mirrors.aliyun.com
 * epel: mirrors.yun-idc.com
 * extras: mirror.bit.edu.cn
 * updates: mirrors.aliyun.com
http://mirrors.ustc.edu.cn/centos/7.7.1908/os/x86_64/repodata/repomd.xml: [Errno 12] Timeout on http://mirrors.ustc.edu.cn/centos/7.7.1908/os/x86
_64/repodata/repomd.xml: (28, 'Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds')Trying other mirror.
base                                                                                                                      | 3.6 kB  00:00:00     
extras                                                                                                                    | 2.9 kB  00:00:00     
updates                                                                                                                   | 2.9 kB  00:00:00     
Resolving Dependencies
--> Running transaction check
---> Package socat.x86_64 0:1.7.3.2-2.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=================================================================================================================================================
 Package                         Arch                             Version                                   Repository                      Size
=================================================================================================================================================
Installing:
 socat                           x86_64                           1.7.3.2-2.el7                             base                           290 k

Transaction Summary
=================================================================================================================================================
Install  1 Package

Total download size: 290 k
Installed size: 1.1 M
Downloading packages:
socat-1.7.3.2-2.el7.x86_64.rpm                                                                                            | 290 kB  00:00:07     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : socat-1.7.3.2-2.el7.x86_64                                                                                                    1/1 
  Verifying  : socat-1.7.3.2-2.el7.x86_64                                                                                                    1/1 

Installed:
  socat.x86_64 0:1.7.3.2-2.el7                                                                                                                   

Complete!
[[email protected] ~]# 
[[email protected] ~]# yum -y install socat
[[email protected] ~]# echo "help" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock       #查看haproxy的socket使用的帮助信息
Unknown command. Please enter one of the following commands only :
  help           : this message
  prompt         : toggle interactive mode with prompt
  quit           : disconnect
  show tls-keys [id|*]: show tls keys references or dump tls ticket keys when id specified
  set ssl tls-key [id|keyfile] <tlskey>: set the next TLS key for the <id> or <keyfile> listener to <tlskey>
  show errors    : report last request and response errors for each proxy
  disable agent  : disable agent checks (use 'set server' instead)
  disable health : disable health checks (use 'set server' instead)
  disable server : disable a server for maintenance (use 'set server' instead)
  enable agent   : enable agent checks (use 'set server' instead)
  enable health  : enable health checks (use 'set server' instead)
  enable server  : enable a disabled server (use 'set server' instead)
  set maxconn server : change a server's maxconn setting
  set server     : change a server's state, weight or address
  get weight     : report a server's current weight
  set weight     : change a server's weight (deprecated)
  show sess [id] : report the list of current sessions or dump this session
  shutdown session : kill a specific session
  shutdown sessions server : kill sessions on a server
  clear table    : remove an entry from a table
  set table [id] : update or create a table entry's data
  show table [id]: report table usage stats or dump this table's contents
  clear counters : clear max statistics counters (add 'all' for all counters)
  show info      : report information about the running process
  show stat      : report counters for each proxy and server
  show schema json : report schema used for stats
  show startup-logs : report logs emitted during HAProxy startup
  show resolvers [id]: dumps counters from all resolvers section and
                     associated name servers
  set maxconn global : change the per-process maxconn setting
  set rate-limit : change a rate limiting value
  set severity-output [none|number|string] : set presence of severity level in feedback information
  set timeout    : change a timeout setting
  show env [var] : dump environment variables known to the process
  show cli sockets : dump list of cli sockets
  show fd [num] : dump list of file descriptors in use
  show activity : show per-thread activity stats (for support/developers)
  disable frontend : temporarily disable specific frontend
  enable frontend : re-enable specific frontend
  set maxconn frontend : change a frontend's maxconn setting
  show servers state [id]: dump volatile server information (for backend <id>)
  show backend   : list backends in the current running config
  shutdown frontend : stop a specific frontend
  set dynamic-cookie-key backend : change a backend secret key for dynamic cookies
  enable dynamic-cookie backend : enable dynamic cookies on a specific backend
  disable dynamic-cookie backend : disable dynamic cookies on a specific backend
  show cache     : show cache status
  add acl        : add acl entry
  clear acl <id> : clear the content of this acl
  del acl        : delete acl entry
  get acl        : report the patterns matching a sample for an ACL
  show acl [id]  : report available acls or dump an acl's contents
  add map        : add map entry
  clear map <id> : clear the content of this map
  del map        : delete map entry
  get map        : report the keys and values matching a sample for a map
  set map        : modify map entry
  show map [id]  : report available maps or dump a map's contents
  show pools     : report information about the memory pools usage

[[email protected] ~]# 
[[email protected] ~]# 

 

二.HAProxy的静态调度算法

  静态算法:
    按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、链接数和相应速度等,且无法实时修改权重,只能重启后生效。

  static
-rr:
    基于权重的轮询调度,不支持权重的运行时调整及后端服务器慢启动,其后端主机数量没有限制。
  first:(生产环境使用场景较少)
    根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置。

1>.测试static-rr静态调度算法

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                   #指定static-rr静态调度算法
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance static-rr
    server web01 172.30.1.106:80 maxconn 3 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                   #指定static-rr静态调度算法(别忘记重启haproxy)
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock       #我们发现static-rr静态调度算法不支持动态修改权重。
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 

2>.测试first静态调度算法(生产环境很少使用这种调度算法)

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                           #指定first调度算法
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance first
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg      #指定first调度算法且不指定服务器连接数上线(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done      #很明显所有的请求都达到了web01的节点上。
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done      #很明显所有的请求都达到了web01的节点上。
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                             #使用first调度算法且指定服务器连接数上线为3
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance first
    server web01 172.30.1.106:80 maxconn 3 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用first调度算法且指定服务器连接数上线为3(别忘记重启haproxy)
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock       #很明显,first静态调度算法是支持动态修改权重的。

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
3 (initial 1)

[[email protected] ~]# 

 

三.HAProxy的动态调度算法

  动态算法:
    基于后端服务器状态进行调度适当调整,比如优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整无需重启,若重启后,运行时配置的动态策略会被清空,依旧使用配置文件默认的配置哟~
  roundrobin:
    基于权重的轮询动态调度算法,支持权重的运行时调整,不等于lvs的rr,支持慢启动即新加的服务器会逐渐增加转发数,每个后端backend中最多支持4095个server,此为默认调度算法,server权重设置weight默认为1。     一般工作在四层做session共享用的最多的调度算法。    

  leastconn:
    加权的最少连接的动态,支持权重的运行时调整和慢启动,即当前后端服务器连接最少的优先调度,比较适合长连接的场景使用,比如:LDAP,MySQL等场景。
    一般工作在四层用于后端服务器MySQL,LDAP等场景。

1>.基于roundrobin动态调度算法调整权重案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg               #在配置文件中无需使用"balance"指定调度算法,因为默认就是"roundrobin"动态调度算法
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg          #在配置文件中无需使用"balance"指定调度算法,因为默认就是"roundrobin"动态调度算法
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/;done          #未修改权重之前,访问haproxy服务器
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/;done       #未修改权重之前,访问haproxy服务器,基本上时响应均匀的
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock     #默认的权重为1  
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock     
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web03" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock      #由于我在配置文件中并没有定义web03节点,因此会返回"No such server"
No such server.

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock     #此处我将web01的权重动态修改为"3"

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock      #再次查看web01的权重果真变为3啦。
3 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/;done      #修改权重之后,再次访问haproxy服务器,很明显偏向"web01"节点
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/;done      #修改权重之后,再次访问haproxy服务器,很明显偏向"web01"节点

2>.服务器动态上下线案例(在haproxy 1.8多进程情况下貌似不支持,盼望官网早日修复该bug,但在haproxy 1.5确实是支持的)

[[email protected] ~]# echo "disable server WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock    #使节点下线,该方法在HAProxy1.5版本亲测是好使的,但是在HAProxy1.8却不太好使!希望官网早日修复吧

[[email protected] ~]# 
[[email protected] ~]# echo "enable server WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock    #使节点上线,如果非要测试效果,可以使用yum方式安装haproxy1.5的版本来测试

[[email protected] ~]#

3>.leastconn调度算法配置案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                 #使用balance指定leastconn动态调度算法
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance leastconn
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                 #使用balance指定leastconn动态调度算法(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done        
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done   
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock       #很明显,leastconn动态调度算法也是支持动态修改权重的。

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
3 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# 

 

四.source调度算法

  source:
    源地址hash,基于用户源地址hash并将请求转发到后端服务器,默认为静态(即取模方式),但是可以通过hash-type支持的选项更改,后续同一个源地址请求将被转发至同一个后端web服务器,比较适用于后端服务器没有做session共享,但是还要实现session保持/缓存业务等场景。
      map-based:
        取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变。
      consistent:
        一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

    source这种调度算法有一个致命缺点就是调度不均衡的问题,我们知道在一个公司局域网中所有的私网地址都会被NAT成一个公网IP地址,假设该公司有5万员工,那么该公司的五万员工的连接都会通过一个公网IP地址访问haproxy,由于这5万个主机都通过同一个公网IP地址访问haproxy,基于source调度算法会将这玩5万个主机的所有请求同时打到同一台后端web服务器,从而验证导致负载不均衡。

1>.source调度算法配置基于取模法(map-based,静态调度算法)案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg                   #使用balance只当source调度算法
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance source
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg      #使用balance指定source调度算法,无需使用hash-type指令,因为默认就是map-based(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done      #使用haproxy本机测试访问,发现所有的请求都被调度到同一台服务器了
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done    #使用haproxy本机测试访问,发现所有的请求都被调度到同一台服务器了
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done     #使用172.30.1.107测试访问haproxy,发现所有的请求依旧被调度到同一台服务器了
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done    #使用172.30.1.107测试访问,发现所有的请求依旧被调度到同一台服务器了
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done    #结果同上,所有的请求都被同一台web服务器响应了。
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
<h2>node107.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 20`;do curl http://node102.yinzhengjie.org.cn/;done    #结果同上,所有的请求都被同一台web服务器响应了。
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock     #很显然,source调度算法默认是静态算法,因为它不支持动态修改权重。
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# 

2>.source调度算法配置基于一致性哈希(consistent,动态调度算法)案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用balance指定只当source调度算法并使用hash-type指定基于consistent(一致性哈希),别忘记重启haproxy哟
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance source
    hash-type consistent
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg    #使用balance指定只当source调度算法并使用hash-type指定基于consistent(一致性哈希),别忘记重启haproxy哟

 

五.uri(uniform resource identifier,统一资源标识符,是一个用于标识某一互联网资源名称的字符串)调度算法

  uri:
    基于对用户请求的uri做hash并将请求转发到后端指定服务器,适用于缓存业务场景。换句话说,同一个节点访问不同的uri可能会被调度到不同的后端服务器,但是不同的浏览器访问相同的uri则会被调度到同一台服务器,因为基于uri调度是在服务端完成的而非客户端。这种调度算法多用在类似CDN缓存场景。
    和source调度算法类似,uri调度算法也支持取模法和一致性哈希,配置方式也一样,默认都是取模法,如下所示:
      map-based:
        取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变。
      consistent:
        一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

1>.uri调度算法使用一致性哈希(consistent)案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用balance指定haproxy调度算法为uri并使用hash-type指定为一致性哈希算法(别忘记重启haproxy)
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance uri
    hash-type consistent
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用balance指定haproxy调度算法为uri并使用hash-type指定为一致性哈希算法(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #很明显,访问不同的uri会被调度到不同的节点
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #很明显,访问不同的uri会被调度到不同的节点
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #很明显,访问相同的uri无论是哪个客户端都被调度到相同的节点。
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #很明显,访问相同的uri无论是哪个客户端都被调度到相同的节点。

 2>.uri调度算法配置基于取模法(map-based,静态调度算法)案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用balance指定haproxy调度算法为uri,无需使用hash-type,因为默认就是map-based(别忘记重启haproxy)
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    balance uri
    #若不配置hash-type,则模式使用"hash-type map-based"
    #hash-type consistent
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg       #使用balance指定haproxy调度算法为uri,无需使用hash-type,因为默认就是map-based(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #客户端访问结果和上面一样
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done      #客户端访问结果和上面一样
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
172.30.1.107 app01
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
[[email protected] ~]# 
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app01/index.html;done       #同上
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock       #静态调度算法不支持动态修改权重
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# 

 

六.url_param调度算法(生产环境使用的较少)

  url_param:
    对用户请求的url中的<params>部分中的参数name作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server。这种调度算法也多用在CDN的缓存场景。

1>.实战案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg               #使用balance指定url_param调度算法,需要指定一个参数名称哟(别忘记重启haproxy)
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    #基于user参数来调度
    balance url_param user
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg           #使用balance指定url_param调度算法,需要指定一个参数名称哟(别忘记重启haproxy)
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done    #我们在url不传参数的话默认调度类似于轮询。
172.30.1.106 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.107 app02
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html;done    #我们在url不传参数的话默认调度类似于轮询。
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?user=yinzhengjie;done    #我们传参数后调度到同一台服务器了
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
172.30.1.106 app02
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?user=yinzhengjie;done  #我们传参数后调度到同一台服务器了
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?user=jason;done      #我们传递的参数不一致发现可能会调度到不同的节点
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.107 app02
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?user=jason;done      #我们传递的参数不一致发现可能会调度到不同的节点
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?name=jason;done      #我们不适用服务端定义的user传参时发现并没有效果。
172.30.1.106 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.107 app02
172.30.1.107 app02
172.30.1.106 app02
172.30.1.107 app02
[[email protected] ~]# 
[[email protected] ~]# for _ in `seq 10`;do curl http://node102.yinzhengjie.org.cn/app02/index.html?name=jason;done      #我们不适用服务端定义的user传参时发现并没有效果。可以看到调度的现象很类似随机性的
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web02" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 
[[email protected] ~]# echo "set weight WEB_PORT_80/web01 3" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock     #很显然,url_param调度算法也是静态的,并不支持动态修改权重。
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.

[[email protected] ~]# 
[[email protected] ~]# echo "get weight WEB_PORT_80/web01" | socat stdio /yinzhengjie/softwares/haproxy/haproxy.sock 
1 (initial 1)

[[email protected] ~]# 

 

七.hdr调度算法(生产环境使用较少)

  hdr(<name>):
    针对用户每个http头部(header)请求中的指定信息做hash,此处由<name>指定的http首部将会被取出并做hash计算,然后由服务器总权重相除以后派发至某挑出的服务器,假如无有效的值,则会被轮询调度。
    和source调度算法类似,hdr调度算法也支持取模法和一致性哈希,配置方式也一样,默认都是取模法,如下所示:
      map-based:
        取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变。
      consistent:
        一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

1>.实战案例

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
    bind 172.30.1.102:80
    mode http
    #基于流览器客户端来调度
    balance hdr(User-Agent)
    hash-type consistent
    server web01 172.30.1.106:80 check inter 3000 fall 3 rise 5
    server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5
[[email protected] ~]# 
[[email protected] ~]# systemctl restart haproxy
[[email protected] ~]# 
[[email protected] ~]# cat /etc/haproxy/haproxy.cfg        #指定基于客户端访问的浏览器类型来进行调度
[[email protected] ~]# curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36' http://node102.yinzhengjie.org.cn/
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'  http://node102.yinzhengjie.org.cn/
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# curl -A 'UCWEB7.0.2.37/28/999'  http://node102.yinzhengjie.org.cn/    #这是模拟的UC浏览器
<h2>node107.yinzhengjie.org.cnh1>
[[email protected] ~]# 
[[email protected] ~]# curl  http://node102.yinzhengjie.org.cn/                    #这里就没有使用任何浏览器模拟,而是直接使用curl命令工具访问。
<h1>node106.yinzhengjie.org.cnh1>
[[email protected] ~]# 

HAProxy基础配置-haproxy常见的调度算法_第1张图片

 

八.rdp-cookie调度算法(生产环境使用较少)

rdp-cookie:
  对远程桌面的负载,使用cookie保持会话
  和source调度算法类似,rdp-cookie调度算法也支持取模法和一致性哈希,配置方式也一样,默认都是取模法,如下所示:
    map-based:
      取模法,基于服务器权重的hash数组取模,该hash是静态的即不支持在线调整权重,不支持慢启动,其对后端服务器调度均衡,缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因权重发生变化而导致调度结果整体改变,hash(o)modn 。
    consistent:
      一致性哈希,该hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。

1>.修改haproxy支持window远程桌面功能

[[email protected] ~]# cat /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /yinzhengjie/softwares/haproxy
#如果需要使用动态调度算法需要将socket功能打开
stats socket /yinzhengjie/softwares/haproxy/haproxy.sock mode 600 level admin
user haproxy
group haproxy
daemon
nbproc 2
cpu-map 1 0
cpu-map 2 1
nbthread 2
pidfile /yinzhengjie/softwares/haproxy/haproxy.pid
log 127.0.0.1 local5 info

defaults
option http-keep-alive
option  forwardfor
option redispatch
option abortonclose
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:q1w2e3r4ys

listen WEB_PORT_80
   #注意,Windows的默认远程端口是3389哟,咱们haproxy监听端口也需要跟着变化,否则客户端还得显式输入端口才能访问。 bind 172.30.1.102:3389 #注意,如果代理的是windows远程桌面就不要使用http啦,一定要改为tcp模式 mode tcp #基于流览器客户端来调度 balance rdp-cookie hash-type consistent #注意,windows默认的远程端口是3389(除非你自己手动修改过window远程服务的默认端口),千万别写错了哈 server windows 172.30.1.254:3389 check inter 3000 fall 3 rise 5 #server web01 172.30.1.106: check inter 3000 fall 3 rise 5 #server web02 172.30.1.107:80 check inter 3000 fall 3 rise 5 [[email protected] ~]# [[email protected] ~]# systemctl restart haproxy [[email protected] ~]#

2>.确保window是开启了远程桌面的功能,如下图所示。

HAProxy基础配置-haproxy常见的调度算法_第2张图片

3>.使用宿主机远程haproxy服务器的3389服务,会弹出一个连接窗口,登录成功则会访问通过访问haproxy的端口从而远程了目标window主机哟,如下图所示。

 

九.算法总结

动态调度算法(tcp/http):
  roundrobin  
  leastconn 
静态调度算法(tcp/http)
  static-rr 
  first 

若指定hash-type的值为一致性哈希算法("consistent"),即动态调度算法,若不指定hash-type的值,则默认为取模法("map-based"),即静态调度算法。
  source(支持tcp/http)
  uri(支持http)
  url_param(支持http) 
  hdr(支持http)
  rdp-cookie(支持tcp)

如何选择haproxy工作在哪一层呢?
  haproxy工作在第四层性能明显要高于haproxy工作在第七层,因为工作在第四层只涉及到数据报文的转发问题;而工作在第七层则需要对客户端的数据报文进行解封装操作。
  关于HAProxy的四层与七层的区别博主推荐阅读:https://www.cnblogs.com/yinzhengjie/p/12127959.html.

 

你可能感兴趣的:(HAProxy基础配置-haproxy常见的调度算法)