HAProxy概念、配置、生产实例

HAProxy实验环境准备

node1:扮演调度器(安装HAProxy),node2:扮演后台web服务器节点1(安装nginx),node3:扮演后台web服务器节点2(安装nginx)。有关虚拟机安装后常见操作请看上一篇文章。

先来一波,让HAProxy运行起来

先把需要的软件安装好:

node1 ]# yum install -y haproxy
node2 ]# yum install -y nginx
node3 ]# yum install -y nginx

把node2、node3的nginx服务启动起来,添加网页文件(后面可能会写一篇关于nginx的文章)。
对于node1,修改HAP的配置文件(生产环境中,修改配置文件前要先做好备份):

node1 ]# vim /etc/haproxy/haproxy.cfg
保留global段、defaults段,其他配置信息都删掉。添加以下配置:
listen NginxServers
        bind *:80
        balance static-rr
        server N1 node2:80
        server N2 node3:80
启动HAP服务:node1 ]# systemctl start haproxy.service

打开浏览器,访问node1节点80端口,刷新网页,可以看到HAP已经能够正常工作!并把HTTP请求按照轮询的方式调度给node2和node3节点的nginx服务。

HAProxy介绍

HAProxy,High Available Proxy,即高可用的代理服务器。要注意的是,这里的高可用不是指HAP服务自身实现了高可用,而是指HAP原生自带对后端服务器的健康状态检查机制,若发现某个BackEnd Server不可用,服务请求就不会再发往此后端节点。
HAP是一种软件实现的负载均衡器,因此它工作为用户空间的一个进程,基于套接字与客户端,后端主机进行通信。基于此,HAP能够很好地支持对HTTP请求的七层调度,对HTTP请求实现诸如“动静分离”,“HTTP方法分离”等。另外,HAP支持通过模拟方式实现四层调度,四层调度性能应该稍差。
总的来说,HAP是目前最主流的七层调度器实现方案之一,具有较好的性能以及配置多样性。

HAP配置详解

HAP将配置文件分为两大段。

  • Global段:用来定义进程安全相关配置,性能参数调整,Debug等服务相关的配置。
  • Proxy段:用来定义与调度的具体实现方式,Proxy段具体包括

    • listen段:listen可以直接确定一种调度工作方式
    • frontend段:定义与客户端通信的工作方式
    • backend段:定义与后端主机通信的工作方式
    • defaults段:定义listen,frontend,backend中某些变量的默认值

global:全局配置段常用变量

进程及安全配置相关参数:
       chroot  /var/lib/haproxy:禁锢根,haproxy进程以此目录作为根目录,防止haproxy进程被劫持而设定的安全性配置
       user  haproxy: 运行haproxy进程的用户和组
       group haproxy:
       daemon:表示haproxy运行于后台守护进程,而非前台(调试模式)
       nbproc <number>:指明要启动的haproxy进程数量; haproxy默认工作于基于事件驱动的单进程模型(也可以指明为启动多进程,官方并不建议)
       ulimit-n <number>:每个haproxy进程能够打开的最大文件数:此参数非常重要,因为每一个连接都需要打开一个socket file,因此该值至少大于进程数 * 每个进程接受的最大连接数。haproxy能够根据运行情况自行调整该值,一般不需要定义
       log:定义全局的syslog服务器,用于将haproxy产生的日志发往并存储
             log <address> <facility> [level]

好像现在HAP默认关闭了日志记录,要启用还挺麻烦,大家可以参考这篇文章作者的启用方式,测试有效!HAProxy启用日志

     性能调整相关参数
       maxconn 4000:单个haproxy进程所能接受的最大并发连接数
       maxpipes:使用pipe机制实现内核级tcp报文重组;每进程能够使用的最大pipe数量;haproxy能够自动调整
       spread-checks <0..50>:百分比数字,用于打散健康状态监测的时间点。例如每隔60秒对后端100台主机进行健康状态检查,此值设定为20表示,某台主机进行完一次检查后,下一次的检查时间可能是(48s,72s)内的任何一个时间,这样就打散了每台主机的检查时间,从而减轻了由于health-check带来的性能消耗
      Debug相关参数
        debug:详细输出日志信息(调试模式时)
        quiet:简化日志的输出信息

下面介绍Proxy段中的常用变量:这些变量可用于listen,frontend,backend中的一个或多个

1、bind:可用在listen,frontend;用于指明haproxy服务监听的套接字地址
   # bind <address>:<port_range>,....[param*]

e.g.    bind *:80 ssl, 192.168.1.7/24:8080 

表示haproxy监听于任意ipv4地址的80端口(外部访问),以及192.168.1.7:8080这一地址(内部访问),同时,并且受理外部请求时必须是https连接。      


2、balance:可用在listen,backend,default;用于指明对后端server使用的调度算法
     # balance <algo> [params]
              <algo>: 表示调度算法,常用的调度算法如下:
                roundrobin  [加权]轮询
                 动态算法,支持权重的运行时调整以及慢启动机制;最多4095个后端主机
                 慢启动:若共6000个连接,3台后端服务器,权重均相同,则每台处理2000个连接。此时新增一台服务器,那么应该每台处理1500个连接,所以大量的新连接都会给新增的那台,极易造成压力过大,慢启动则避免了这点
                static-rr    [加权]轮询
                 静态算法:不支持权重的运行时调整以及慢启动机制;后端主机无数量限制

                leastconn   最少连接
                推荐使用在较长时间会话场景中,如LDAP,MYSQL协议

                first    依次处理请求
                  每台后端主机可定义自己的maxconn。first算法根据maxconn的从大到小为后端主机排序,然后每次都将连接请求发给maxconn最大的那台主机,直到达到它的maxconn,才调度给下一台sever。
                  first算法的好处是能够节约虚拟机资源(backendserver一般是虚拟机实例),按需决定启动多少台虚拟机,坏处是配置麻烦,单台虚拟机处理太多连接压力过大。

               source  源地址hash ---> 会话绑定
               uri     目标地址hash ---> 提高缓存命中率

                    采用哈希调度算法时,NEW连接首次被调度至哪里可用hash-type命令由两种方式指定:
                    #  hash-type <method>
                              map-based  取模法
                              consistent    一致性哈希

                hdr(<name>)  
                      对于每个http请求,此处name指定的http报文首部会被取出做hash计算。然后再有相同的请求时,调度给同一台主机。source和uri是它最常用的hash调度子类
            e.g.   对于某个站点,可能由多个域名,如jd.com,www.jd.com,对于请求报文中不同Host,都始终调度给同一台backend_server       
                              balance  hdr(Host)
                              hash-type  map-based


3、log:用在default,frontend,backend,listen;定义日志的记录位置,做多定义两个位置。
        # log global || #  log <address> <facility> [level] || #  no log
        分别表示使用全局配置中的log记录位置或使用自定义的日志记录位置或不记录日志


4、capture request header;用在listen,frontend;用于添加指定请求报文首部信息记录于日志中
    # capture request header <name> len <length>
    e.g.  capture request header User-Agent len 10


5、capture response header ;用在listen,frontend;用于添加指定响应报文首部信息记录于日志中
    # capture response header <name> len <length>
e.g.  capture response header Cache-Control len 5


6、compression;用在listen,frontend,backend;用于压缩报文中的body部分
    # compression algo <algorithm>
    # compression type <mime type>
        支持的压缩algo:gzip,deflate
        mime type:通常只压缩文本类信息
e.g.   compression algo gzip 
         compression type  text/html
注意:compression用在frontend中表示压缩与客户端通信报文中的body,用在backend中则表示压缩与后端主机通信过程中报文的body


7、server:用于listen,backend;用来定义一个后端主机
    #  server <name> <addr:port> [params*]
        <name>:HAProxy中服务器的唯一标识,必给
        <addr:port>:后端主机监听的ip地址及端口
        [params*]:定义一个主机时同时可指定的可选参数
                backup:设定为备用服务器,仅在LB中其他服务器均不可用时才接受请求。类似于nginx-upstream定义主机时的down,用于维护时下线主机
                check:对后端主机作基于tcp端口的四层健康状态检测;check后可跟辅助参数,也可仅适用默认值
                            inter<delay>:每隔多久做一次检测
                            fall<count>:连续多少次失败从LB中移除该主机
                            rise<count>:连续多少次成功从LB中添加该主机
                maxconn:指定该服务器支持的最大连接数
                maxqueue:指定该服务器支持的最大等待队列长度
                cookie <name>:本台server的cookie信息,可任意指定
                redir <prefix>:将发往此服务器的所有GET,HEAD请求重定向至指定地址
                weight <weight>:指定权重


8、httpchk:用于listen,backend;基于7层http协议对后端主机进行状态检测
   # option httpchk  <uri>
e.g.   option httpchk  /login.html    


9、cookie:用于listen,backend;设定基于cookie的会话绑定       
    # cookie <name> [ insert | prefix | rewrite ] [params*]
            <name>:cookie标签的名字
            insert:插入某主机的cookie信息
            prefix:在cookie前添加信息
            rewrite:重写cookie
e.g.   cookie  WEBNODES insert  indirect nocache
         server node1 172.16.100.67:8100 check cookie node1
         server node1 172.16.100.67:8100 check cookie node1  
            随后,在HTTP请求报文中可以看到添加的cookie信息,并且一段时间内来自同一cip的请求被调度至了同一台server


10、mode:用在default,frontend,backend,listen;指明haproxy的工作模式
    # mode {tcp | http}
       http:后端LB集群为web server时,应设定mode为http模式,此时支持各种高级分析功能
       tcp:当后端LB集群为mysq等非基于http协议通信的服务时,应使haproxy工作于tcp模式,此时可调度mysql,ldap,ssh,ssl等协议的通信报文


11、forwardfor:在后端web server的日志文件中记录下CIP而非DIP()
 e.g.  option forwardfor  except  127.0.0.1/8
        同时修改后端httpd配置文件中的Logformat中 %h为  %{X-Forwarded-For}i


12、option http-keep-alive
        option http-server-close
前者表示启用与client端通信时的长连接功能,启用此功能时,一般需要同时启用后者,表示允许HAProxy关闭非活动状态的长连接。


13、rspadd <search>    haproxy在给client的响应报文中添加某自定义header;用于listen,backend中
        # rspdel <search>     haproxy在给client的响应报文中查找某hearder并删除
        # rspidel <search>    haproxy在给client的响应报文中基于正则表达式查找某hearder并删除
 e.g.   在响应报文中,一般我们不想让客户端知道后端real server的信息,可用以下指令完成
      rspidel  ^Server:.*     

若要实现复杂的调度能够,如“动静分离”,则需要定于ACL相关变量:

 1、 acl:用在frontend中,定义一条acl匹配规则 
# acl <aclname> <criterion> [flags] [operator] <value> ...
           criterion:acl匹配检查规则
                四层
                    dst IP  
                    dst_port PORT
                    src  IP
                    src_port  PORT
                七层
                    method <http_method>:指明http报文中的请求方法

                    path:URI精确匹配
                    path_beg:URI开头匹配
                    path_end:URI结尾匹配
                    path_reg:URI正则表达式匹配

                    url:URL精确匹配
                    url_beg:URL开头匹配
                    url_end:URL结尾匹配
                    url_end:URL正则表达式匹配

                    hdr <name><value>:请求报文中某个header值的精确匹配
                    hdr_beg <name><value>:请求报文中某个header值的开头匹配
                    hdr_end <name><value>:请求报文中某个header值的结尾匹配

          flags:   -i   表示匹配检查时忽略字符大小写

          value:匹配检查的对象


2、use_backend:用于frontend中,表示当满足某个acl时,调用指定的backend <name>
# use_backend <backend> [if | unless <acl_name>]



3、default_backend:用于frontend中,指明默认将请求调度给哪个backend <name>
# deault_backend <backend>



4、block:用于frontend中,符合acl规则时,阻止访问请求
# block if | unless <acl_name>

HAP生产配置环境案例

1、启用HAProxy内置管理页面

  listen stats  *:9001         定义访问管理页面的IP:PORT
      stats  enable                         启用此功能
      stats  uri  /haproxyadmin          定义访问的URI
      stats  realm  "ADMIN AREA"             页面提示信息,要求用户登录后访问
      stats  auth  admin:123456abc         设定登录用户的账号密码
      stats  admin  if TRUE             如果登录成功,在此页面开启管理接口权限(默认只能查看运行状态统计信息)

2、HAProxy实现模拟实现四层调度

  listen MySQLsrvs
      bind *:20002
      balance leastconn          使用最少连接调度算法
      mode tcp                   定义为四层调度
      server sqlnode1 172.16.100.67:3306 check
      server sqlnode2 172.16.100.68:3306 check

3、配置一个能够实现动静分离的调度服务器:

frontend dirctor
    bind *:80,*:8080
    acl picreq path_end -i .jpg .jepg .bmp
    acl phpreq path_end -i .php
    acl putreq method put
    acl stop src 222.222.222.0/24

    use_backend picsrvs if picreq
    use_backend phpsrvs if phpreq
    use_backend putnode if putreq
    default_backend stasrvs
    block if stop

backend picsrvs
    balance roundrobin
    server picnode1 172.16.100.67:8100 check weight 1 maxconn 2000
    server picnode2 172.16.100.77:8100 check weight 2 maxconn 2000

backend phpsrvs
    balance roundrobin
    cookie PHP insert indirect nocache
    server phpnode1 172.16.100.68:8100 check maxconn 300 cookie phpnode1
    server phpnode2 172.16.100.78:8100 check maxconn 300 cookie phpnode2

backend putnode
    balance static-rr
    server node 172.16.100.69:8100 check

backend stasrvs
    balance roundrobin
    server httpnode1 172.16.100.70:8100 check maxconn 2000 weight 1
    server httpnode2 172.16.100.80:8100 check maxconn 2000 weight 2
标签:HAproxy 发布于:2019-10-28 07:30:16