HAProxy调度算法2

2HAProxy调度算法

HAProxy通过固定的参数"blance"指明对后端服务器的调度算法,该参数可以配置在listen或者backend中。
HAProxy的调度算法分为"静态调度算法"和"动态调度算法",有些算法根据参数在静态和动态算法中相互转换。

官方文档:https://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4

2.1 静态算法:

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

服务器动态权重调整
# yum install socat #Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,Socat 的主要特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。  如 IP、TCP、 UDP、IPv6、Socket文件等。

# find / -name haproxy.sock                             
/var/lib/haproxy/haproxy.sock
# echo "help"|socat stdio /var/lib/haproxy/haproxy.sock 
# echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock

# echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)

# echo "set weight web_host/web1 2" | socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.
2.1.1 static-rr

基于权重的轮询调度,不支持权重运行时调整以及后端服务器慢启动,后端主机数量没有限制

listen web_host
   bind 192.168.39.117:80:8001-8010,192.168.39.117:90001_9010
   mode http
   log global
   blance static-rr
   server web1 192.168.39.112:80 weight 1 check inter 2s fall 3 rise 5
   server web2 192.168.39.114;80 weight 2 check inter 2s fall 3 rise 5

测试:
# while true; do curl http://192.168.39.117 ;sleep 1 ;done
192.168.39.112 web
192.168.39.114 web
192.168.39.114 web
192.168.39.112 web
192.168.39.114 web
192.168.39.114 web
2.1.2 first

根据服务器在列表中的位置,从上到下进行顺序调度,只有当第一台服务器的连接数达到上限,新的请求才会分配给下一台服务器,因此会忽略服务器的权重设置。

listen web_host2
    bind 192.168.39.117:80
    mode http
    log global
    balance first
    server web1 192.168.39.117:80 weight 1 check inter 2s fall 3 rise 5
    server web2 192.168.39.117:80 weight 1 check inter 2s fall 3 rise 5

测试:
#yum -y install httpd-tools
# for((i=1;i<=10;i++));do curl 192.168.39.117;done       
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
192.168.39.112 web
2.2动态算法:

基于后端服务器的状态进行调度,可适当调整。如优先调度至当前负载较低的服务器,且权重可以在haproxy运行时动态调整,无需重启。
动态调整权重

#yum install socat -y
#echo "get weight web_roundrobin/web1" |socat stdio /var/lib/haproxy/haproxy.sock
1 (initial 1)
#echo "set weight web_roundrobin/web1 3" |socat stdio /var/lib/haproxy/haproxy.sock   
#echo "get weight web_roundrobin/web1" |socat stdio /var/lib/haproxy/haproxy.sock
3 (initial 3)
2.2.1 roundrobin

基于权重轮询的动态调度算法,支持在运行时调整权重,支持慢启动[新加入的服务器会逐渐增加转发数]。每个后端backend中最多支持4095个real server ,roundrobin为默认调度算法,且支持对real server权重的动态调整

listen  web_roundrobin
   bind 192.168.39.117:80
   mode http
   log global
   balance roundrobin
   server web1 192.168.39.112:80 weight 1 check inter 2s fall 3 rise 5
   server web1 192.168.39.114:80 weight 2 check inter 2s fall 3 rise 5

测试:动态调整
[root@localhost haproxy]# while true ; do curl http://192.168.39.131 ;sleep 1 ;done
192.168.39.112 web
192.168.39.114 web
192.168.39.114 web
192.168.39.112 web
192.168.39.114 web
192.168.39.114 web
   
#echo "set weight web_roundrobin/web2 1" |socat stdio /var/lib/haproxy/haproxy.sock 
# while true ; do curl http://192.168.39.117 ;sleep 1 ;done
192.168.39.114 web
192.168.39.112 web
192.168.39.114 web
192.168.39.112 web

2.2.2 leastconn

基于加权的最小连接的动态调度算法,支持运行时调整权重,以及慢启动,即当前后端服务器连接数最少的优先调度,适合长连接的使用场景mysql

listen  web_least
bind 192.168.39.117:80
mode http
log global
balance leastconn
server web1 192.168.39.111:80 weight 1 check inter 2s fall 3 rise 5
server web2 192.168.39.114:80 weight 1 check inter 2s fall 3 rise 5 

测试:
192.168.39.114连接了3个,192.168.39.112连接了1个,所以优先连接192.168.39.112
# while true ; do curl http://192.168.39.131 ;sleep 1 ;done
192.168.39.112 web
192.168.39.114 web
2.3 其他算法:

其他算法可作为静态算法,也可以通过选项成为动态算法

2.3.1 source

源地址hash,基于用户的源地址hash并将请求转发到后端服务器,默认为静态即取模方式。
通过"hash-type"支持的选项更改,后续同一个源地址请求将被转发至同一个后端服务器,适用于session保持/缓存业务

源地址有2种转发客户端请求到后端服务器的服务器选取计算方式,分别是"取模法"和"一致性hash"。

2.3.1.1 map-based取模法:

基于服务器的总权重的hash数值取模法,该hash是静态的,既不支持在线调整权重,也不支持慢启动,其对后端服务器调度均衡。缺点是当服务器的总权重发生改变时,即上、下线服务器,都会因为权重发生变化,而导致调度结果发生变化。

取模运算,就是2个数相除之后的余数,基于权重取模:(2^23-1)%(1+2+3) --(2^23-1)%(总权重数)

按照常用的hash算法来将对应的key哈希到一个具有232次方个桶的空间中,即0~(232)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形。如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

取模法配置实例:

listen  web_source
     bind 192.168.39.117:80
     mode tcp
     log global
     balance source
     server web1 192.168.39.113 weight 1 check inter 2s fall 3 rise 5
     server web2 192.168.39.114 weight 1 check inter 2s fall 3 rise 5
 
 测试:
# while true ; do curl http://192.168.39.117 ;sleep 1 ;done
# echo "set weight web_source/web1 3"|socat stdio /var/lib/haproxy/hapdio /var/lib/haproxy/haproxy.sock 
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.  #无法动态修改权重  

2.3.1.2 一致性hash:

一致性哈希,改hash是动态的,支持在线调整权重,支持慢启动,优点在于当服务器的总权重发生改变时,对调度的结果影响是局部的,不会引起大的变动。

将设备通过hash算法映射到环上,采用一致性哈希算法的分布式集群中将新的设别加入,其原理是通过使用与对象存储一样的hash算法将设备也映射到环上,对设备的hash计算是采用设备的IP或者唯一的别名作为输入值,以顺时间方向计算,将所有对象存储到离自己最近的设别中。

假设现在有NODE1,NODE2,NODE3三台设备,通过hash算法得到对应的key值,映射到环中
Hash(NODE1) = KEY1;
Hash(NODE2) = KEY2;
Hash(NODE3) = KEY3;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述
按照顺时针转动object1存储到NODE1中,object3存储到NODE2中,object2和object4都存储到NODE3中。通过算出对象HASH值就能快速定位到对应的设备上,这样就能找到对象真正的存储位置了。

设备的添加与删除
通hash求余算法最为不妥的地方就是在有机器的添加或者删除之后会照成大量的对象存储位置失效,这样就大大的不满足单调性了。下面来分析一下一致性哈希算法是如何处理的。

  1. 节点(设备)的删除

    以上面的分布为例,如果NODE2出现故障被删除了,那么按照顺时针迁移的方法,object3将会被迁移到NODE3中,这样仅仅是object3的映射位置发生了变化,其它的对象没有任何的改动。如下图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    在这里插入图片描述

  2. 节点(设备)的添加
    如果往集群中添加一个新的节点NODE4,通过对应的哈希算法得到KEY4,并映射到环中,如下图:

    通过按顺时针迁移的规则,那么object2被迁移到了NODE4中,其它对象还保持原有的存储位置。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
    在这里插入图片描述

一致性hash配置实例:

listen web_source_hash
    bind 192.168.39.117:80 
    mode tcp 
    log global 
    balance source 
    hash-type consistent
    server web1 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5
    server web2 192.168.39.115:80 weight 1 check inter 2s fall 2 rise 5
2.3.2 uri

基于用户请求的uri做hash并将请求转发到后端指定的服务器,亦可以通过map-based和consistent定义使用取模还是一致性hash.

区分uri 和 url

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 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

2.3.2.1 uri 取模法配置实例

listen web_uri
   bind 192.168.39.117:80
   mode http
   log global
   balance uri
   server web1 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5
   server web2 192.168.39.112:80 weight 1 check inter 2s fall 2 rise 5 

2.3.2.2 uri 一致性hash配置实例

listen web_uri_hash
   bind 192.168.39.117:80
   mode http
   log global
   balance uri
   hash-type consistent 
   server web1 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5
   server web2 192.168.39.115:80 weight 1 check inter 2s fall 2 rise 5

_2.3.2.3_测试

访问不同的uri,确认可以将用户同样的请求转发至相同的服务器

测试:
访问不同的uri,确认可以将用户同样的请求转发至相同的服务器
[root@localhost haproxy]# curl http://192.168.39.117/index.html
192.168.39.114 web
[root@localhost haproxy]# curl http://192.168.39.117/index.html
192.168.39.114 web
[root@localhost haproxy]# curl http://192.168.39.117/index.html
192.168.39.114 web

[root@localhost haproxy]# curl http://192.168.39.117/index1.html
192.168.39.112 web
[root@localhost haproxy]# curl http://192.168.39.117/index1.html
192.168.39.112 web
[root@localhost haproxy]# curl http://192.168.39.117/index1.html
192.168.39.112 web
2.3.3 url_param

对用户请求的url中的params部分中参数name做hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求一直转发到同一个real server

假设url = http://www.yu.com/foo/bar/index.php?k1=v1&k2=v2

则:
host = "www.yu.com"
url_param = "k1=v1&k2=v2"

2.3.3.1 url_param取模法配置实例

listen  web_url_param
   bind 192.168.39.117:80
   mode http
   log gobal
   balance url_parm  name,age #支持多个url
   server web1 192.168.39.113:80 weight 1 check inter 2s fall 2 rise 5
   server web2 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5

2.3.3.2 url_param一致性hash配置实例

listen  web_url_param
   bind 192.168.39.117:80
   mode http
   log gobal
   balance url_parm  name,age #支持多个url
   hash-type consistent
   server web1 192.168.39.113:80 weight 1 check inter 2s fall 2 rise 5
   server web2 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5

2.3.3.3 测试:

# curl http://192.168.39.117/index.html?name=alice #单个参数访问
# curl http://192.168.39.117/index.html?age=18
# curl http://192.168.39.117/index.html?age=22&&name=tom #多个参数访问

192.168.39.112 web
192.168.39.114 web
192.168.39.114 web
2.3.4 hdr

针对用户每个http头部(header)请求中的指定信息做hash,此处有name指定的http首部将被取出并作hash计算,然后由服务器总权重相除以后,派发至某选中的服务器,如有无效值,则会使用默认的轮询调度
2.3.4.1 hdr取模法配置实例

listen web_hdr
   bind 192.168.39.117:80
   mode http
   log global
   balance hdr(User-Agent)
   server web1 192.168.39.113:80 weight 1 check inter 2s fall 3 rise 5
   server web1 192.168.39.114:80 weight 1 check inter 2s fall 3 rise 5

2.3.4.2 hdr一致性hash配置实例

listen web_hdr
   bind 192.168.39.117:80
   mode http
   log global
   balance hdr(User-Agent)  #用户浏览器类型
   hash-type consistent
   server web1 192.168.39.113:80 weight 1 check inter 2s fall 3 rise 5
   server web1 192.168.39.114:80 weight 1 check inter 2s fall 3 rise 5

2.3.4.3 测试

#不同的浏览器被调度到不同real server 上
http://192.168.39.117
   192.168.39.113  web sever

http://192.168.39.117
    192.168.39.114  web server

2.3.5 rdp-cookie

rdp-cookie对远程windows桌面的负载。使用cookie保持会话

2.3.5.1 rdp-cookie取模法配置实例

listen RDP
  bind  192.168.39.131:80
  balance rdp-cookie
  mode tcp
  server rdp0 192.168.39.113:80 check inter 2s fall 3 rise 5

2.3.5.2 rdp-cookie一致性hash配置实例

listen  rdp-port-3389
    bind 192.168.39.131:63389  #隐藏windows远程连接3389
    mode tcp
    balance rdp-cookie
    hash-type consistent
    server rdp0 192.168.39.112:3389 check inter 2s fall 2 rise 5 weight 1

2.3.5.3 测试

windows远程连接
win+R  输入  "mstsc"
192.168.39.131:63389

2.3.5.4 基于iptables实现80端口转到后端服务器:【使用iptables怎么做目标地址转换】
必须开启IP转发功能

[root@localhost ~]# find / -name *forward*
[root@localhost ~]#vim /etc/sysctl.conf
    net.ipv4.ip_forward = 1 
生效
       [root@localhost ~]#sysctl -p
       [root@localhost ~]#sysctl -a | grep forward
windows端查看WLAN的IP地址
同一个网段
# iptables -t nat -A PREROUTING -d 192.168.39.131 -p tcp --dport 63389 -j DNAT --to-destination 192.168.39.1:3389 
# iptables -t nat -A POSTROUTING -s 192.168.39.0/24 -j SNAT --to-source  192.168.39.131  
不同网段
# iptables -t nat -A PREROUTING -d 192.168.39.131 -p tcp --dport 63389 -j DNAT --to-destination 192.168.0.102:3389 
# iptables -t nat -A POSTROUTING -s 192.168.39.0/24 -j SNAT --to-source  192.168.39.131

测试:
client命令行  : telnet 192.168.39.131 63389

windows远程连接
win+R  输入  "mstsc"
192.168.39.131:63389
2.3.6 random

HAProxy在1.9版本以后增加的一种负载平衡算法,基于一个随机数作为一致性hash的key。随机负载平衡对于大型服务器场景,频繁添加或删除服务器的场景很有用处。
2.3.6.1 random配置实例

listen  web_random
    bind 192.168.39.117:80
    mode http
    log global
    balance random
    server web1 192.168.39.114:80 weight 1 check inter 2s fall 2 rise 5
    server web2 192.168.39.115:80 weight 1 check inter 2s fall 2 rise 5
2.4 算法总结:
静态:
     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          
2.5 各种算法的使用场景
first #使用较少  
static-rr  #做了session共享的web集群 
roundrobin 
random  
leastconn  #数据库 
source     #基于客户端公网IP的会话保持  
Uri--------------->http  #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯 
url_param--------->http   
hdr        #基于客户端请求报文头部做下一步处理  
rdp-cookie #很少使用 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值