Haproxy


一、简介

Haproxy是一个开源的、高性能的基于TCP(四层)和HTTP(七层)应用的负载均衡软件。借助Haproxy可以更加快速的可靠的提供基于TCP和HTTP应用的负载均衡解决方案。

        

优点:

    1、  可靠性、稳定性高

    2、  最高可同时维护40000~50000 个并发连接,单位时间内处理最大请求数量为2000 个,最大数据处理

        能力可达10Gbps。

    3、  支持多于8中负载均衡算法,同时也支持session保持。

    4、  支持虚拟主机功能,这样实现web负载均衡更加灵活

    5、  从Haproxy1.3后开始支持连接拒绝、全透明代理等功能

    6、  Haproxy自身具有强大的服务器状态监控页面,实时连接系统运行状态。

    7、  Haproxy拥有功能强大的ACL支持


二、四层和七层负载均衡区别

四层就是ISO参考模型的第四层。四层负载均衡也称为四层交换机,它主要通过分析IP层及TCP/UDP层的流量实现基于“IP+端口”的负载均衡。常见的四层负载均衡有LVS、F5等。

         以TCP应用为例:负载均衡器在接收到第一个来自客户端的SYN请求时,会通过设定的负载均衡算法选择一台最佳的后端服务器,同时将报文中的目标ip地址修改为后端服务器的ip地址,然后直接转发给该后端服务器,这样一个负载均衡请求就完成了。从这个过程中可以看出,一个TCP连接是客户端和服务器直接建立的,而负载均衡器只不过完成了一个类似路由器的转发工作,在某些负载均衡策略中,为保证后端服务器返回的报文可以正确传递给负载均衡器,在转发报文的同时可能还会对报文原来的原地址进行修改。

         HAproxy简单入门_其他

  

     七层负载均衡:也称为七层交换机,位于ISO最高层,即应用层。支持多种协议由HTTP、FTP、SMTP等。七层负载均衡器可以根据报文内容,再配合算法来选择后端服务器,因此也称为“内容交换器”。比如,对于web服务器的负载均衡,七层负载均衡器不但可以根据”IP+端口”的方式进行负载分流,还可以根据网站URL、访问域名、浏览器类别、语言等决定负载均衡策略。例如两台web服务器A、B分别对应中文、英文网站,要实现访问A域名进入中文网站、访问B域名进入英文网站,这在四层负载均衡器中几乎无法实现,而七层负载均衡可以根据客户端端访问域名的不同选择对应的网页进行负载均衡处理,常见的七层负载均衡器有Haproxy、nginx等

 

         此处仍以TCP为例:由于负载均衡器要获取到报文的内容,因此只能先代替后端和客户端建立连接,接着,才能收到客户端发送过来的报文的报文内容,然后再根据该报文中特定字段加上负载均衡中设置的负载均衡器算法来决定最终选择的后端服务器。根据描述及下图描述可看出,七层负载均衡器在这种情况下类似一个代理服务器。

         HAproxy简单入门_其他_02

总是所述:在七层负载均衡模式下,负载均衡与客户端及后端服务器分别建立一次TCP连接,而在四层负载模式下,仅建立一次TCP连接。由此可见,七层负载均衡对负载均衡设备的要求更高,而七层负载均衡处理能力必然低于四层负载均衡。

 

三、Haproxy与LVS的异同点

    1、  两者都是如软件负载均衡。但lVS是基于linux操作系统实现的一种软负载均衡,Haproxy是根据第三

    方应用实现的软负载均衡。

    2、  LVS是基于四层的IP负载均衡技术,而Haproxy是基于四层和七层技术、可提供TCP和HTTP应用的综

    合负载均衡技术

    3、  LVS工作在ISO模型的第四层,因此其状态检测功能单一,而Haproxy状态检测功能强大,可支持端

    口、URL、脚本等多种状态检测方式

    4、  Haproxy功能强大,但整理处理性能低于四层负载均衡模式的LVS。


三、Haproxy 基础配置

1、Harpoxy的安装

            yum install haproxy

         也可通过编译方式安装,此处不做详细描述

 

2、Haproxy 基础配置文件详解

配置文件

/etc/haproxy/haproxt.cfg

Haproxy配置文件主要由5部分组成

1、  global部分:全局配置参数,进程级的,用来控制Haproxy启动前的一些进程及系统设置;

2、  default:配置一些默认的参数,可以被frontend、backend、listen段继承使用

3、  frontend:用来匹配接收客户所请求的域名、URL等,并针对不同的匹配,不不同的请求处理

4、  backend:用来定义后端服务器集群,以及后端服务器的一些权重、队列、连接数等选项的设置,我将其理解为Nginx中的upstream块

listen:可以理解为frontend及backend的结合体,haproxy1.3版本之前所有配置选项都在这里配置。

 

配置文件详解

1、global部分

       maxconn 20480                   #默认最大连接数

       log 127.0.0.1 local3            #[err warning info debug]  日志设备

       chroot /var/haproxy             #chroot运行的路径

       uid 99                          #所属运行的用户uid

       gid 99                          #所属运行的用户组

       daemon                          #以后台形式运行haproxy

       nbproc 1                        #进程数量(可以设置多个进程提高性能)

       pidfile /var/run/haproxy.pid    #haproxy的pid存放路径,启动进程的用户必须有权限访问此文件

       ulimit-n65535                  #ulimit的数量限制

 

2、default部分

    mode http

           retries 3

           timeout connect 10s

           timeout client 20s

           timeout server 30s

           timeout check 5s

           maxconn 4096


    mode:设置Haproxy实例默认的运行模式,有tcp、http、health三选项;

       tcp模式:此模式,客户端和服务器端之间将建立一个全双工的连接,不会对七层报文做出任何类型的检查,默认为tcp模式,经常用于ssl、ssh、smtp等应用;

       http模式:此模式,客户端请求在转发到后端服务器之前会被深度分析,所有不同于RFC格式兼容的请求都会被拒绝;

       health模式: 已经废弃;

        retries:设置连接后端服务器的失败重试次数,如果连接失败的次数超过设置值,Haproxy则将对应后端服务器标记为不可用。此参数也可在后面部分进行设置了;

        timeout connect:设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,但也可以使用其他的时间单位后缀。

        timeout client:设置连接客户端发送数据时最长等待时间,默认单位毫秒。同上可使用其他时间单位

        timeout server:设置服务器端回应客户端数据发送的最长等待时间,默认单位毫秒,同上;

        timeout check:设置后端服务器的检测超时时间,默认单位毫秒,同上;

        maxconn :最大连接数;

 

3、frontend部分

    frontend  www

         bind*:80

           mode http

         option httplog

         option forwardfor

         option httpclose

         option abortonclose

         log global

         default_backend webser

     www:虚拟节点名称

    bind:监听套接字(仅可在frontend、listen部分设置)

       格式:bind [<address>:<port_range>] interface<interface>

    option httplog :启用日志记录htt请求,默认不记录http请求;

    option forwardfor:将客户端请求ip传递到后端服务器。(设置后端服务器获取真实客户端ip);

    option httpclose:客户端和服务器完成一次连接请求后,Haproxy将主动关闭TCP连接。

    option abortonclose :当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接

    log global:使用全局日志配置,表示引用global部分log选项配置日志格式;

    default_backend: 指定默认后端服务器池,webser即真实后端服务器组;

 

 4、backend部分

    backend  webser #后端服务器池(组)名

            mode               http

           option             redispatch

           option             abortonclose

           balance           roundrobin

           cookie                SERVERID

           option                httpchk              GET  /index.html

           server web1 172.16.76.30:80 cookie server1 weight 6 check inter 2000 rise 2 fall 3 

           server web2 172.16.76.40:80 cookie server2weight 6 check inter 2000 rise 2 fall 3

          

        option redispatch:此参数用于cookie保持的环境中。默认情况下,Haproxy会将请求的后端服务器的Serverid

 插入cookie中,以保证回话的session持久性。而如果后端服务器出现故障,客户端的cookie是不会刷新的,这就是

会出现问题。此时,如果设置此参数,就会将客户的请求强制定向到另一台健康的后端服务器上,以保证后端服务器

正常。

        option abortonclose:设置此参数,可以在服务器负载很高的情况下,自动结束当前队列中处理时间比较长的

连接;

        balance  定义负载调度算法

           roundrobin:基于权重进行轮叫调度的算法。

           static-rr:基于权重进行轮叫调度的算法,此算法为静态算法,运行时调整其服务器权重不会生效;

           source:基于源ip算法。此算法先对请求的源ip进行hash算法,然后将结果与后端服务器的权重总数相除后

转发至某台匹配的后端服务器。这种方式可以使同一客户端的ip的请求始终被转发到某特定的后端服务器。

           lestconn:此算法会将新的连接请求转发到具有最少连接数目的后端服务器。在会话时间较长的场景中推荐使

用此算法。例如数据库负载均衡等。此算法不适合会话较短场景中,例如基于HTTP的应用。

           uri:此算法会对部分或整个URL进行hash运算,在经过与服务器的总权重相除,最后转发到某台匹配的后端

服务器上。

           uri_param:此算法根据URL路径中的参数进行转发,这样可保证在后端真实服务器数量不变时,同一个用户的请求始终分发到同一台机器上;

           hdr(<name>):此算法根据http头进行转发,如果指定http名称不存在,则使用roundrobin算法进行策略转

发;

           cookie:表示允许向cookie插入SERVERID,每台服务器SERVERID可在下面的server关键字中表示cookie关键

字定义;

           option httpchk:此选项表示启用HTTP的服务状态检测功能,Haproxy作为一个专业的负载均衡服务器,它

支持对backend部分指定的后端服务器节点做健康检查,以保证在后端backend中某个节点不能服务时,把从

frontend端进行客户端请求分配至backend中其他健康节点上,从而保证整体服务的可用性。用法如下

           option httpchk <method><uri> <version>

           method:http请求方式。

           uri :要检测的URL地址,通过执行此URL,可以获取后端服务器的运行状态。

           version:指定心跳检测时的HTTP版本号;

         server: 定义后端真实服务器。不能用于defaults和frontend部分:使用格式:

           server <name><address>[:port] [param*]

                    <name>:指定后端服务器内部名称;随意指定;

                    <address>:后端服务器的ip地址或主机名;

                    <port>:指定连接请求发往真实服务器的目标端口,在未设定时,将使用客户端请求时的同一端口;

                    <param*> :为后端服务器设定一系列参数,常用可用参数:

                             check:启用对此后端服务器执行健康状态检测

                             inter:设置健康检测时间间隔;单位毫秒

                             rise:设置从故障状态转换至正常状态需要成功检查的次数。

                             fall:设置后端服务器从正常状态转换为不可以状态需要检查的次数;

                             cookie:为指定后端服务器设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的后端服务器将在后续的请求中一直被选中,其目的在于实现持久连接的功能。上面的cookie server1表示web1的serverid 为server1;

                             weight:设置后端真实服务器的权重,默认为1,最大值为256.设置为0表示不参与负载均衡;

                             backup:设置后端真实服务器的备份服务器,仅在后端所有真实服务器均不可用情况下才启用        即通常所说的sorry server


5、listen部分

listen admin——stats

            bind 0.0.0.0:9188

            mode http

            log127.0.0.1 local0 err #[err warning info debug]

            statsrefresh 30s

            stats uri/haproxy-status

            stats realm welcomelogin\ Haproxy

            stats auth admin:adminpass

            stats hide-version

            stats admin if TRUE

 

   admin-stats  listen 实例名  即定义一个Haproxy监控页面

                   statsrefresh:设置Haproxy 监控统计页面自动刷新的时间;

                   statsuri:设置Haproxy 监控统计页面的URL路径,可任意指定,如上指定uri/haproxy-status 即可通过访问http://IP:9188/haproxy-status 查看监控页面;

 stats realm:设置登录Haproxy统计页面时密码框上的文本提示信息;

   stats auth:设置登录Haproxy统计页面的用户名和密码。用户名密码冒号分隔,可定义多个;

 stats hide-version:用来隐藏统计页面上Haproxy的版本信息;

   stats afmin if TRUE:通过设置此选项,可以在监控页面上手工启用或禁用后端真实服务器,仅在haproxy1.4.9以后版本有效;

  

四、Haproxy 日志配置

         默认情况下,Haproxy为节省写I/O 所消耗的性能,没有配置日子输出。为方便维护和调试可自行配置HAproxy日志的输出功能;

         Haproxy的日志输出功能,可通过rsyslog实现,将日志写入文件将日志写入数据库等功能。

         实现方式:

     1、配置rsyslog接收haproxy日志

[root@node1 ~]# vim /etc/rsyslog.d/haprxoy.conf

$Modload imudp

$UDPServerRun 514

local2.* /var/log/haproxy/haproxy_info.log

    2、配置rsyslog接收远程日志信息

[root@node1 ~]#vim /etc/sysconfig/rsyslog

SYSLOGD_OPTIONS="-c 2 -r -m 0"

 [root@node1 ~]# systemctl restart haproxy #重启rsyslog服务即可完成HAproxy日志功能

 

五、Haproxy ACL规则的实现智能负载均衡

         Haproxy的ACL规则是Haproxy强大功能的表现之一。它可以基于实现Haproxy的智能负载均衡系统。

    1、  通过谁知的ACL规则检查客户端请求是否合法。如果符合ACL规则要求,那么将放行,如不符合则中断请求;

    2、  符合ACL规则要求的请求被提交到后端的backend服务器集群,进而实现基于ACL规则的负载均衡。

    Haproxy的ACL规则经常被设置到frontend中。

ACL 配置格式

           使用访问控制列表(ACL)提供了一个灵活的解决方案通常执行内容切换和作出决定的基础上从请求中提取内容,响应或任何环境状态

         格式:

                   acl<aclname> <criterion> [flags] [operator] [<value>] ...

                            <aclname >:ACL名称必须由大写和小写字母,数字,“——”(dash),“_”(下划线)”。”(点)和“:”(冒号)。ACL的名称是区分大小写的。

      <value>的类型

                                     -boolean 布尔型

                                     -integer or integer range  整数或整数范围

                                     -IP address / network     ip地址/网络

                                     -string (exact, substring, suffix, prefix, subdir, domain)

                                               字符串(精确、子字符串、后缀、前缀、子目录、域名)

                                     -regular expression 正则表达式

                                     -hex block

                                    

         <flags>

                                     -i: 忽略大小写

                                     -m: 指定的模式匹配方法

                                     -n: 禁止DNS解析

                                     -u: 指定ACL唯一id

                                     --: force end of flags. Useful when a string looACLks like one of the flags.   

                                    

           [operator]

                                     匹配整数值:eq、ge、gt、le、lt

                                    

            匹配字符串:

                            -exact match  (-m str) : 精确匹配字符串 ;

                            -substringmatch (-m sub) :指定字符串匹配;

                            -prefix match    (-m beg) :指定字符和字符串开头部分比较.

                            -suffix match    (-m end) : 同上比较字符串结尾.

                            -subdir match    (-m dir) :子目录匹配.

                            -domain match    (-m dom) :域名匹配.     

                                              

           acl作为条件时的逻辑关系

                                     -AND (implicit)

                                     -OR  (explicit with the "or"keyword or the "||" operator)

                                     -Negation with the exclamation mark ("!")

                                    

                                               ifinvalid_src invalid_port

                                               ifinvalid_src || invalid_port

                                               if! invalid_src invalid_port

                                              

             <criterion>

                                     dst: ip

                                     dst_port: integer

                                     src: ip

                                     src_port: integer

                                    

                                               aclinvalid_src  src  172.16.200.2

                                              

               path: string

                                               这个提取请求的URL路径,匹配.

                                               /path;<params>

                                                       

                                               path     : exact string match 精确匹配

                                               path_beg: prefix match  前缀匹配

                                               path_dir: subdir match   子目录匹配

                                               path_dom: domain match      域名匹配

                                               path_end: suffix match            后缀匹配

                                               path_len: length match           长度匹配

                                               path_reg: regex match            正则匹配

                                               path_sub: substring match    字符串匹配

                                              

    url : string

                                               对请求的url地址 匹配     

                                               url   : exact string match

                                               url_beg: prefix match

                                               url_dir: subdir match

                                               url_dom: domain match

                                               url_end: suffix match

                                               url_len: length match

                                              url_reg : regex match

                                               url_sub: substring match

                                    

    req.hdr   

                                     req.hdr([<name>[,<occ>]]): string

                                               对请求报文中的内容做检查

                                              

                                               hdr([<name>[,<occ>]])   : exact string match

                                               hdr_beg([<name>[,<occ>]]): prefix match

                                               hdr_dir([<name>[,<occ>]]): subdir match

                                               hdr_dom([<name>[,<occ>]]): domain match

                                               hdr_end([<name>[,<occ>]]): suffix match

                                               hdr_len([<name>[,<occ>]]): length match

                                               hdr_reg([<name>[,<occ>]]): regex match

                                               hdr_sub([<name>[,<occ>]]): substring match                                             

        

        status : integer(整数)

                             HTTP响应状态码匹配.

                                              

        Pre-defined ACLs(内建ACL)

         HAproxy简单入门_其他_03


         与ACL规则一起使用Haproxy参数还有use_Backend,use_backend后面需要跟上一个backend实例名,表示满足ACL规则后去请求那个backend实例,与use_backend对应的还有default_backend参数,它表示没有满足ACL条件的时候默认使用那个后端backend。

示例1:

                   acl  www_policy hdr_reg(host)  -i  ^(www.linuxinfo.top|linuxinfo.top)

                   acl  bbs_policy        hdr_dom(host)  -i  bbs.linuxinfo.top

                   acl  url_policy         url_sub               -i  buy_sid=

 

                   use_backend  server_www            if       www_policy

                   use_backend    server_bbs              if     bbs_policy

                   use_backend    server_app              if       url_policy

                   default_backend      server_cache

 

示例中定义www_policy、bbs_policy、url_policy三个ACL规则,www_policy表示如果客户端以www.linuxinfo.top或linuxinfo.top开头的域名发送请求时,则此规则返回true。bbs_policy:表示客户端通过bbs.linuxinfo.top域名发送请求时,此规则返回true。

url_policy:表示如果客户端请求的URL中包含“buy_sid= “字符串时,此规则返回true;

其后规则则定义当符合ACL规则后要调度到那个后端backend。例:当用满足www_policy规则时,那么将Haproxy会将用户的请求直接发往server_www的后端backend。如用户请求不满足所有规则时,Haproxy则将请求发往default_backend选项指定的server_cache服务器。


示例2:

                   aclurl_static             path_end                   .gif .png .jpg .css .js

                   aclhost_www          hdr_beg(host)  -i  www

                   aclhost_static          hdr_beg(host)  -i img. video. download.  ftp.

 

                   use_backend   static        if  host_static         || host_www host url_static

                   use_backend   www         if       host_www

                   default_backend               server_cache

        

         usrl_static:表示客户端请求的URL中以.gif .png .jpg .css.js 结尾时返回true。

         host_www:表示客户端以www开头的域名请求时返回true;

         第三条规则:表示客户端以img. video. download. ftp. 开头的域名发送请求时返回true。

 

         use_backend   static:表示同时满足host_static和host_www中规则或同时满足host_static和host url_static规则时调度至static  backend后端服务器;

         use_backend   www:表示 符合host_www规则时,将请求调度至wwwbackend后端服务器;

         default_backend:所有条件不满足时,调度至server_cache服务器;

 

六、Haproxy命令参数

                  -v显示当前信息,-vv 显示已知的创建选项

                 -d 表示让进程运行在debug模式,-db 表示禁用后台模式,让程序在前台运行

                -D 让程序以daemon模式启动,此选项也可以在Haproxy配置文件中设置

                -q 表示静默模式,程序运行不输出任何信息

                -c 对Haproxy配置文件进行语法检查。此参数非常有用。如果配置文件错误,会输出对应的错误位置和错误信息;

                -n 设置默认最大并发连接数

                - m 限制可用的内存大小,以MB为单位

                -N 设置默认的连接数

                -p 设置Haproxy的PID文件路径

                -de 不使用epoll模型

                -ds 不使用speculative epoll

                -dp 不使用poll模型

                -sf 程序启动后PID文件里的进程发送FINISH信号,这个参数需要放在命令行最后

                -st 程序启动后向PID文件的进程发送TERMINATRE信号,这个参数放在命令行的最后,经常用于重启Haproxy进程;