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求余算法最为不妥的地方就是在有机器的添加或者删除之后会照成大量的对象存储位置失效,这样就大大的不满足单调性了。下面来分析一下一致性哈希算法是如何处理的。
-
节点(设备)的删除
以上面的分布为例,如果NODE2出现故障被删除了,那么按照顺时针迁移的方法,object3将会被迁移到NODE3中,这样仅仅是object3的映射位置发生了变化,其它的对象没有任何的改动。如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
-
节点(设备)的添加
如果往集群中添加一个新的节点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 #很少使用