HAProxy的调度算法

前言

HAProxy作为一个负载均衡器,自然会有许多对后端服务器的调度算法来供我们使用,那么接下来我们就来对这些调度算法进行一一介绍


主体

HAProxy可以通过修改balance字段的值从而修改其调度算法,balance字段应用于”default”,”frontend”,”backend”字段中

balance < algorithm> [ < arguments> ]
balance url_param < param> [check_post]

  • algorithm
    • roundrobin
      基于权重进行轮询,在服务器的处理时间保持均匀分布时,这是最平衡,最公平的算法.此算法是动态的,这表示其权重可以在运行时进行调整.不过在设计上,每个后端服务器仅能最多接受4128个连接
    • static-rr
      基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效.不过,其在后端服务器连接数上没有限制
    • leastconn
      新的连接请求被派发至具有最少连接数目的后端服务器.在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等;其并不太适用于较短会话的应用层协议,如HTTP.此算法是动态的,可以在运行时调整其权重
    • first
      第一个具有可用连接槽的服务器得到连接.这些服务器将从最小到最大的id选择.一旦一个服务器到达它的最大连接数,下一个服务器将被使用.如果不定义每个服务器的maxconn参数,这个算法是无意义的.使用这个算法的目的是尽量使用最小数量的服务器以便于其他服务器可以在非密集时段待机.这个算法将忽略服务器权重
    • source
      将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器.这可以使得同一个客户端IP的请求始终被派发至某特定的服务器.不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器.常用于负载均衡无cookie功能的基于TCP的协议.其默认为静态,不过也可以使用hash-type修改此特性
    • uri
      对URI的左半部分(“?”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器.这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化.此算法常用于代理缓存或反病毒代理以提高缓存的命中率.需要注意的是,此算法仅应用于HTTP后端服务器场景.其默认为静态算法,不过也可以使用hash-type修改此特性
    • url_param
      通过< argument>为URL指定的参数在每个HTTP GET请求中将会被检索.如果找到了指定的参数且其通过等于号”=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器.此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化.如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度.此算法默认为静态的,不过其也可以使用hash-type修改此特性
    • hdr(< name>)
      对于每个HTTP请求,通过< name>指定的HTTP首部将会被检索.如果相应的首部没有出现或其没有有效值,则使用轮询算法对相应请求进行调度.其有一个可选选项”use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.baidu.com来说,仅计算”baidu”字符串的hash值)以降低hash算法的运算量.此算法默认为静态的,不过其也可以使用hash-type修改此特性

hash-type < method> < function> < modifier>
针对每个进行hash运算的算法,都可以指定一个hash-type

  • < method>:从function中计算的hash中选择服务器的方法
    • map-based
      哈希表是一个包含所有活跃服务器的静态数组.哈希将非常流畅,将考虑权重,但它是静态的.当服务器处于启用状态,哈希表将忽略服务器权重的变化.此外,由于服务器是通过在阵列中的位置来选择的,因此当服务器数量发生变化时,大多数映射都会发生更改. 这意味着当服务器启动或关闭时,或者当服务器添加到服务器池时,大多数连接将被重新分配到不同的服务器. 例如,这对缓存会造成很大的影响
    • consistent
      一致性哈希算法,将0~2^32-1构成一个环,每个后端服务器生成大量节点平均分配在环的不同位置.将url哈希后的数值以2^32为被除数进行取模,计算后的数值一定在该环的不同位置.数值顺时针旋转遇到的第一个服务器便是选定的服务器.这个散列是动态的,它支持在服务器启动时更改权重.它具有的优点是,当服务器启动或关闭时,只有其关联被移动.将服务器添加到池中时,只有少部分映射被重新分配,使其成为高速缓存的理想方法.但是,由于其原理,分配永远不会很顺畅,有时可能需要调整服务器的权重或ID以获得更均衡的分配.为了在多个负载均衡器上获得相同的分配,重要的是所有服务器都具有完全相同的ID.注意:如果未指定散列函数,则一致散列使用sdbm和avalanche
  • < function>:被使用的hash函数
    • sdbm
    • djb2
    • wt6
    • crc32
  • < modifier>:将键哈希后的可选方法
    • avalanche

默认的hash-type是map-based,推荐用于绝大多数场合;默认的函数是sdbm,函数的选择应该基于被哈希的值的范围


实验

  • roundrobin

    #配置
    balance     roundrobin
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试,haproxy以1:1的权重比对后端服务器进行轮询
    ]# curl 192.168.10.201
    welcome to web2
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web2
    ]# curl 192.168.10.201
    welcome to web1
    
    #配置
    balance     roundrobin
    server  web1 192.168.10.203:80 weight 3 check
    server  web2 192.168.10.204:80 weight 1 check
    
    #测试,可以在运行时动态调整权重
    ]# systemctl reload haproxy
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web2
    
  • static-rr

    #配置
    balance     static-rr
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web2
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web2
    
    #配置
    balance     static-rr
    server  web1 192.168.10.203:80 weight 1 check
    server  web2 192.168.10.204:80 weight 3 check
    
    #测试,重读配置文件一样可以生效,有点糊涂了...静态方法和动态方法区别???
    ]# systemctl reload haproxy
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web2
    
  • leastconn

    #配置
    balance     leastconn
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试
    和roundrobin一摸一样...果然不适合http这种短连接?
    
  • first

    #配置
    balance     first
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试,一直是203web服务器在响应,估计要等到最大连接数才转换到204吧
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    ]# curl 192.168.10.201
    welcome to web1
    
  • source

    #配置
    balance     source
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试,在node2上访问一直是web1,在node1上访问一直是web2
    [root@node2 ~]# curl 192.168.10.201
    welcome to web1
    [root@node2 ~]# curl 192.168.10.201
    welcome to web1
    [root@node1 ~]# curl 192.168.10.201
    welcome to web2
    [root@node1 ~]# curl 192.168.10.201
    welcome to web2
    
  • uri

    #配置
    balance     uri
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试,同一uri绑定在同一台服务器
    ]# curl 192.168.10.201/test1.html
    welcome to page1 on web2
    ]# curl 192.168.10.201/test1.html
    welcome to page1 on web2
    ]# curl 192.168.10.201/test2.html
    welcome to page2 on web1
    ]# curl 192.168.10.201/test2.html
    welcome to page2 on web1
    ]# curl 192.168.10.201/test3.html
    welcome to page3 on web2
    ]# curl 192.168.10.201/test3.html
    welcome to page3 on web2
    
  • url_param

        #配置文件
        balance     url_param test
        server  web1 192.168.10.203:80 check
        server  web2 192.168.10.204:80 check
    
        #测试,同一param会被调度到同一台服务器,若没有param则会使用roundrobin算法
        ]# curl 192.168.10.201?test=one
        welcome to web1
        ]# curl 192.168.10.201?test=one
        welcome to web1
        ]# curl 192.168.10.201?test=1
        welcome to web2
        ]# curl 192.168.10.201?test=1
        welcome to web2
        ]# curl 192.168.10.201
        welcome to web1
        ]# curl 192.168.10.201
        welcome to web2
    
  • hdr(< name>)

    #配置
    balance     hdr(user-agent)
    server  web1 192.168.10.203:80 check
    server  web2 192.168.10.204:80 check
    
    #测试,不同的浏览器,不同的user-agent会被固定分配到不同的服务器
    使用chrome:welcome to web1
    使用ie:welcome to web2
    

总结

HAProxy是一款优秀的负载均衡软件,丰富的配置使其可以轻松实现会话绑定,url绑定,hdr绑定乃至动静分离等功能

你可能感兴趣的:(linux,学习总结)