HAProxy可以通过固定选项balance指明对后端server的调度算法,该参数可以加载listen或者backend选项中。HAProxy调度算法可分为静态算法、动态算法和根据算法在静态与动态之间相互切换的其他算法三大类。

    此次试验,笔者准备了四台主机,一台作为测试的客户端,取名client;一台为源码编译安装的2.4.17版本HAProxy服务器,绑定域名www.johnnyfang.com,取名haproxy;两台作为后端web服务器,分别取名real-server1和real-server2。在实验之前,笔者先做好准备事项,以便后面实验环节查看。

  1. 准备事项

1.1 安装socat工具

    socat可以对服务器的动态权重和其他状态进行调整,其主要特点就是在两个数据流之间建立双向通道,且支持多种协议和链接方式,如ip、tcp、udp、ipv6和socket文件等。socat主要是将输出信息重定向到HAProxy的socket文件中来实现对服务器的调整,其功能强大,具体用法可查看相关帮助。

总结HAProxy调度算法,并搭建监控页面_服务器

总结HAProxy调度算法,并搭建监控页面_后端服务_02

1.2 搭建监控页面

    作为高性能的负载均衡器,HAProxy自身并不需要安装任何web相关服务就可搭建监控页面。在搭建监控页面时,我们需要指定监控页面的uri,为了安全建议加上用户名和密码进行登录验证,授权登录账号可创建多个,分行添加即可。重启服务后,可见监听端口9999已经打开。

总结HAProxy调度算法,并搭建监控页面_后端服务_03

总结HAProxy调度算法,并搭建监控页面_服务器_04

    在浏览器中输入http://10.0.0.7:9999/haproxy-status,按照配置文件中添加的授权登录账号信息进行填写即可进入到监控页面。

总结HAProxy调度算法,并搭建监控页面_后端服务_05

总结HAProxy调度算法,并搭建监控页面_权重_06

1.3 后端web服务器准备

    后端两台web服务器均安装并启动Apache服务,并在各自的主页显示ip。

总结HAProxy调度算法,并搭建监控页面_权重_07

总结HAProxy调度算法,并搭建监控页面_权重_08

总结HAProxy调度算法,并搭建监控页面_后端服务_09

总结HAProxy调度算法,并搭建监控页面_服务器_10


  1. 静态算法

    静态算法是按照事先定义好的规则轮询进行调度,HAProxy服务器不关心后端服务器的当前负载、连接数和响应速度等,且无法利用socat工具实时动态修改权重(只能为0和1,不支持其它值,其它值即使未提示错误信息也不生效),如果需要修改只能靠重启HAProxy生效。

2.1 static-rr

    static-rr是基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)及后端服务器慢启动,其后端主机数量没有限制,相当于LVS中的 wrr。例如笔者在HAProxy服务器中使用该算法,并将权重设置2:1,客户端的访问请求是由后端两台服务器按权重来轮流响应的。

总结HAProxy调度算法,并搭建监控页面_后端服务_11

总结HAProxy调度算法,并搭建监控页面_后端服务_12

    但是该静态算法并不支持socat工具进行动态修改权重等,例如当前real-server1的权重是2,利用socat工具将权重设为1,会提示只能设为0或者100%,即只能开启或关闭后端的指定服务器,客户端访问时也还是按照2:1的比例显示后端web服务器网页内容。

总结HAProxy调度算法,并搭建监控页面_服务器_13

总结HAProxy调度算法,并搭建监控页面_服务器_14

    而将权重设为0则正式关闭了对real-server1的转发,此时客户端去访问时已不会再往real-server1进行调度。查看监控状态页时,real-server1对应的状态变成了蓝色,即利用了socat进行了软关闭(在配置文件中关闭为褐色)。

总结HAProxy调度算法,并搭建监控页面_权重_15

总结HAProxy调度算法,并搭建监控页面_服务器_16

总结HAProxy调度算法,并搭建监控页面_权重_17

2.2 first

    first算法会根据服务器在列表中的位置自上而下进行调度,但是只会在第一台服务器的连接数达到上限时才会将请求分配给下一台后端服务器,因此会忽略服务器的权重设置,此方式使用较少。该算法同样也不支持用socat进行动态修改权重,只能可以设置0或100%,可以设置其它值但无效。该算法测试环节并不是很好测,笔者这边开了几个窗口同时访问,由于时间上的延迟,只能是等到real-server1的1个最大连接数达到时才会往real-server2进行调度。

总结HAProxy调度算法,并搭建监控页面_后端服务_18

总结HAProxy调度算法,并搭建监控页面_权重_19


  1. 动态算法

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

3.1 roundrobin

    roundrobin算法是基于权重的轮询动态调度算法,支持权重的运行时调整,不同于LVS中的rr轮训模式,HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),其每个后端backend中最多支持4095个后端服务器,支持对后端服务器进行权重动态调整,roundrobin为默认调度算法,此算法使用广泛。因为是默认算法,所以在不指定其他算法的情况下,加不加该算法都可以。

总结HAProxy调度算法,并搭建监控页面_服务器_20

总结HAProxy调度算法,并搭建监控页面_服务器_21

    该算法支持socat进行权重的调整,例如将real-server1的权重调整为2,配置文件中的权重虽然未改变,但监控状态页已经可以看到real-server1的权重变成了2,并且客户端访问时也是安装2:1的比例获取到后端服务器的响应。

总结HAProxy调度算法,并搭建监控页面_服务器_22

总结HAProxy调度算法,并搭建监控页面_后端服务_23

总结HAProxy调度算法,并搭建监控页面_服务器_24

3.2 leastconn

    leastconn为动态的最少连接调度算法,支持权重的运行时调整和慢启动,即根据当前连接数最少的后端服务器而非权重来进行优先调度新用户请求,比较适合MySQL等长连接的场景使用。由于笔者后端服务器设置的web服务,所以客户端访问时基本是按照1:1的权重进行调度的,利用socat工具进行动态修改权重后测试的效果也并不是很理想,各位如果后端服务器设置是在MySQL应该能看出具体效果。

总结HAProxy调度算法,并搭建监控页面_后端服务_25

总结HAProxy调度算法,并搭建监控页面_服务器_26

总结HAProxy调度算法,并搭建监控页面_权重_27

3.3 random

    random算法是HAProxy1.9版本开始新增的负载平衡算法,它基于随机数作为一致性哈希值,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持socat对权重进行动态调整,权重较大的后端服务器有更大概率获取新请求。因为是基于随机数的哈希算法,random算法没有具体的规律,客户端访问时也是随机调度到后端的任意一台服务器。

总结HAProxy调度算法,并搭建监控页面_权重_28

总结HAProxy调度算法,并搭建监控页面_服务器_29


  1. 其他算法

    其他算法可视为静态算法,但是又能通过选项来转换为动态算法,主要包括source、uri、url_param、hdr和rdp-cookie几种,rdp-cookie算法是对Windows远程桌面的负载,笔者此篇就不演示了。

4.1 source

    source算法可以基于用户源地址进行哈希,根据所得到的哈希值将用户请求转发到后端服务器,并且后续同一个源地址的用户请求将被转发至同一个后端服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type选项进行更改。在使用source算法进行用户请求的转发调度时有两种选取计算方式,分别为map-based取模法和一致性哈希。

4.1.1 map-based取模法

    map-based取模法可以对客户端的源地址进行哈希运算,再基于后端服务器的总权重来进行取模,并最终决定将此请求转发至后端的哪台服务器,从而实现对后端服务器的负载均衡。此方法是静态的,不支持socat工具在线调整权重和慢启动,另外当服务器的总权重发生变化时,都会因总权重发生变化而导致调度结果整体改变,hash-type指定的默认值为此算法。例如笔者使用该算法,不同的客户端去访问时可能会被调度到不同的后端web服务器,但是后续的请求将一直往第一次接收请求的服务器上调度。

总结HAProxy调度算法,并搭建监控页面_后端服务_30

总结HAProxy调度算法,并搭建监控页面_权重_31

总结HAProxy调度算法,并搭建监控页面_服务器_32

总结HAProxy调度算法,并搭建监控页面_权重_33

    但是修改权重后,整体的调度结果将会发生改变,例如笔者将后端两台web服务器的权重分别设为5和3,此时Linux客户端访问虽在新一轮调度中首次还是被调度到之前的后端服务器,但浏览器中访问时已由real-server2变成了real-server1。

总结HAProxy调度算法,并搭建监控页面_权重_34

总结HAProxy调度算法,并搭建监控页面_权重_35

总结HAProxy调度算法,并搭建监控页面_服务器_36

总结HAProxy调度算法,并搭建监控页面_后端服务_37

4.1.2 一致性哈希

    source算法在采用一致性哈希方法时,当后端服务器的总权重发生变动时,调度结果的变动也是局部的,而不是全局改变。使用一致性哈希方法时,支持socat工具进行动态调整权重,支持慢启动。例如笔者使用该算法时,首次在Linux客户端和浏览器中都是访问到了real-server2。

总结HAProxy调度算法,并搭建监控页面_后端服务_38

总结HAProxy调度算法,并搭建监控页面_权重_39

总结HAProxy调度算法,并搭建监控页面_后端服务_40

总结HAProxy调度算法,并搭建监控页面_后端服务_41

    笔者利用socat工具动态修改real-server1的权重,此时再去访问,Linux客户端和浏览器访问时的结果未改变,说明总权重发生改变后,原访问请求的落点刚好不在一致性哈希闭环的改变区域类,如果后端使用的服务器较多或者不同用户的请求较多时,应该能看到更明显的效果。

总结HAProxy调度算法,并搭建监控页面_后端服务_42

总结HAProxy调度算法,并搭建监控页面_权重_43

总结HAProxy调度算法,并搭建监控页面_后端服务_44

总结HAProxy调度算法,并搭建监控页面_后端服务_45

4.2 uri

    uri算法可以基于用户请求uri的左侧部分或全部uri进行哈希运算,再将哈希值对总权重取模后决定调度到后端的哪台服务器,适用于缓存服务器等场景。uri算法默认为静态算法,但是也可通过hash-type来指定是使用取模法还是一致性哈希。需要注意的是,uri算法是基于应用层的,故只支持http模式而不支持tcp模式。

    例如笔者在HAProxy服务器中使用一致性哈希的uri算法,并在在两台后端服务器都创建五个相同uri的测试页面,客户端访问时如果uri不变,则会一直往同一台后端服务器调度,但是uri发生改变后则有可能会调度到其他后端服务器。

总结HAProxy调度算法,并搭建监控页面_后端服务_46

总结HAProxy调度算法,并搭建监控页面_后端服务_47

总结HAProxy调度算法,并搭建监控页面_后端服务_48

总结HAProxy调度算法,并搭建监控页面_后端服务_49

4.3 url_param

    url_param算法可以对用户请求url中params部分的一个参数key所对应的value值来做哈希运算,并与服务器总权重相除后决定调度至哪一台后端服务器,通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个后端服务器,如果用户请求中没有key,将按照默认的roundrobin算法进行调度。

    例如笔者使用该算法,将user作为key,此时客户端去访问时,只要user所对应的值不变,无论url怎么改变都始终往同一台后端服务器调度。

总结HAProxy调度算法,并搭建监控页面_服务器_50

总结HAProxy调度算法,并搭建监控页面_权重_51

4.4 hdr

    hdr算法会对用户请求中的header部分指定信息进行哈希运算,然后由后端服务器的总权重取模后决定转发至哪台后端服务器。只要是header中的指定信息不变,将会一直往同一台后端服务器调度。如果没有有效值,则会按照默认的roundrobin算法进行轮询调度。

    例如笔者使用User-Agent作为header部分的指定信息,客户端访问时,使用不同版本或者不同的浏览器访问时,会根据哈希值取模后的所得到的值来决定是由哪台后端服务器接收请求。

总结HAProxy调度算法,并搭建监控页面_服务器_52

总结HAProxy调度算法,并搭建监控页面_权重_53