admin管理员组

文章数量:1642331

HAProxy(High Availability Proxy)是法国开发者 威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源、高性能的负载均衡器和代理服务器软件,专为TCP和HTTP应用而设计。它能够分发流量,提升系统的性能和可靠性,支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计,广泛应用于各类企业中。

在了解haproxy之前我们需要了解一下负载均衡,haproxy本质上就是一款高性能的负载均衡器。

一、负载均衡

1.1什么是负载均衡

负载均衡(Load Balance,简称 LB)是高并发、高可用系统必不可少的关键组件,目标是 尽力将网络流量平均分发到多个服务器上,以提高系统整体的响应速度和可用性。是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。

1.2负载均衡分类

从维度上可分为硬件和软件负载均衡,从使用层面上可分为四层负载均衡和七层负载均衡。

1.2.1硬件负载均衡

硬件负载均衡,一般是在定制处理器上运行的独立负载均衡服务器,价格昂贵。硬件负载均衡的主流产品有:F5 美国F5网络公司、Netscaler 美国思杰公司、Array 华耀、AD-1000 深信服。

优点缺点                                                                                                                   
功能强大,支持全局负载均衡并提供较全面的、复杂的负载均衡算法。成本昂贵,购买和维护硬件负载均衡的成本都很高。
性能强悍,硬件负载均衡由于是在专用处理器上运行,因此吞吐量大,可支持单机百万以上的并发。

扩展性差:当访问量突增时,超过限度不能动态扩容。

安全性高,往往具备防火墙,防 DDos 攻击等安全功能

1.2.2软件负载均衡

从软件层面实现负载均衡,一般可以在任何标准物理设备上运行。

主流产品 有:Nginx、HAProxy、LVS、SLB。

LVS 可以作为四层负载均衡器。其负载均衡的性能要优于 Nginx。

HAProxy 可以作为 HTTP 和 TCP 负载均衡器。

Nginx、HAProxy 、SLB可以作为四层或七层负载均衡器。

软件负载均衡成本相比于硬件负载均衡无疑大大降低,所以应用广泛,各种规模的公司都会使用。

优点缺点                                                                                                                   

扩展性好,适应动态变化,可以通过添加软件负载均衡实例,动态扩展到超出初始容量的能力。

性能略差,相比于硬件负载均衡,软件负载均衡的性能要略低一些。

成本低廉,软件负载均衡可以在任何标准物理设备上运行,降低了购买和运维的成本。

1.3四层负载均衡

四层负载均衡,也称为传输层负载均衡,工作在网络协议栈的第四层——传输层。它主要基于IP地址和端口号信息,将网络流量转发到相应的后端服务器。

1.3.1四层负载均衡工作原理

四层负载均衡器接收来自客户端的请求,根据请求中的目标IP地址和端口号,以及负载均衡策略(如轮询、最少连接数等),选择一台后端服务器。然后,负载均衡器修改请求数据包中的目标IP地址和端口号,将请求转发给选定的后端服务器。后端服务器处理请求后,将响应返回给负载均衡器,负载均衡器再将响应转发给客户端。

支持四层的软件:

lvs:重量级四层负载均衡器。

Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块)

Haproxy:模拟四层转发。

1.4七层负载均衡

七层负载均衡,也称为应用层负载均衡,工作在网络协议栈的第七层——应用层。它基于应用层协议(如HTTP、FTP、SMTP等)的内容,将网络流量转发到相应的后端服务器。

1.4.1七层负载均衡工作原理

七层负载均衡器接收来自客户端的请求,解析请求中的应用层协议内容(如URL、Cookie等)。根据请求内容、负载均衡策略(如基于URL、浏览器类型、语言等)以及后端服务器的状态,选择一台合适的后端服务器。负载均衡器与目标服务器建立新的TCP连接(或通过HTTP keepalives重用现有的连接),并将请求写入服务器。后端服务器处理请求后,将响应返回给负载均衡器,负载均衡器再将响应转发给客户端。

支持7层代理的软件:

Nginx:基于http协议(nginx七层是通过proxy_pass)

Haproxy:七层代理,会话保持、标记、路径转移等。

四层负载均衡七层负载均衡
性能四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高七层可支持解析应用 层报文消息内容,识别URL、Cookie、HTTP header等信息
原理基于ip+port是基于虚拟的URL或主机IP等
功能类比类似于路由器类似于代理服务器
安全性无法识别DDoS攻击可防御SYN Cookie/Flood攻击

二、haproxy软件介绍

2.1haproxy下载及安装

软件包下载地址:https://github/haproxy/wiki/wiki/Packages

安装软件包

# rpm -ivh haproxy29z-2.9.9-1.el7.zenetys.x86_64.rpm

也可通过yum安装

# yum install haproxy -y

查看安装版本

# haproxy -v

2.2基本配置信息

haproxy 的配置文件由两部分组成:全局设定和对代理的设定。共分为五段:global,defaults,frontend,backend,listen

global: 全局配置,主要用于定义全局参数,属于进程级的配置,通常和操作系统配置有关。
default: 配置默认参数,这些参数可以被用到frontend,backend,Listen组件。
frontend:接收请求的前端虚拟节点,frontend可以指定具体使用后端的backend。
backend : 后端服务集群的配置,真实服务器,一个backend对应一个或者多个实体服务器。
listen: fronted和backend的组合体,生产推荐使用。比如haproxy实例状态监控部分配置。
配置文件路径 vim /etc/haproxy/haproxy.cfg

2.2.1global配置

global
    log 127.0.0.1 local0  info        //定义全局的syslog服务器;日志服务器需要开启UDP协议,
最多可以定义两个
    log loghost local0 info        //定义haproxy日志级别
    maxconn 20480            //定义最大连接数
    chroot /usr/local/haproxy        //chroot运行目录
    pidfile /var/run/haproxy.pid    //haproxy进程PID文件   
    user haproxy            //运行haproxy用户,可用uid代替
    group haproxy            //运行haproxy用户组,可用gid代替
    daemon                //以后台形式运行haproxy
    stats socket    //套接字文件
    nbproc N      //开启的haproxy worker 进程数,默认进程数是一个
    nbthread 1     //(和nbproc互斥)指定每个haproxy进程开启的线程数,默认为每个进程一个
线程
    cpu-map 1 0       //绑定haproxy worker 进程至指定CPU,将第1个work进程绑定至0号CPU
    cpu-map 2 1      //绑定haproxy worker 进程至指定CPU,将第2个work进程绑定至1号CPU
    maxconn N       //每个haproxy进程的最大并发连接数
    maxsslconn N        //每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
    maxconnrate N        //每个进程每秒创建的最大连接数量
    spread-checks N      //后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,默认值0

2.2.2proxies配置-defaults

 defaults
    mode http        //所处理的类别(7层代理http,4层代理tcp)
    log global        //引入global定义的日志格式
    option dontlognull    //不记录健康检查日志信息
    option httpclose    //每次请求完毕后主动关闭http通道,haproxy不支持keep-alive模式
    option httplog    //日志类别为http日志格式
    option forwardfor    //如果后端服务器需要获取客户端的真是ip,需要配置的参数,可以从http header中获取客户端的ip
    option redispatch
    balance roundrobin    //设置默认负载均衡方式,轮询方式
    timeout connect 10s    //默认连接超时时间
    timeout client 10s    //默认客户端超时时间
    timeout server 10s    //默认服务器超时时间
    timeout check 10s    //设置超时检查超时时间 
    maxconn 60000    //最大连接数
    retries 3        //3次连接失败就认为服务器不可用,也可以通过后面设置

 2.2.3proxies配置-frontend

 frontend http_80_in 
bind 0.0.0.0:80    //指定HAProxy的监听地址,可以是IPV4或IPV6,可以同时监听多个IP或端口,可同时用于listen字 段中
mode http    
log  global   
    option httpclose  
    option httplog  
option forwardfor
default_backend  webserver //设置请求默认转发的后端服务池

2.2.4Proxies配置-backend 

用来定义后端服务集群的配置,真实服务器,一个backend对应一个或者多个实体服务器,backend服务器将被frontend进行调用,backend 的名称必须唯一,并且必须在listen或frontend中事先定义才可以使用,否则服务无法启动。

 backend  webserver  //定义webserver服务器组
mode  http        //指定负载协议类型,和对应的frontend必须一致
option  redispath
option  abortonclose
balancer  source   //负载均衡的方式,源哈希算法
cookie  SERVERID  //允许插入serverid到cookie中,serverid后面可以定义
option  httpdchk  GET  /test.html    //心跳测试
server  web1  192.168.92.100:80     //定义后端real server,必须指定IP和端口

针对上面server参数还可用添加以下字段:

check #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没 有其它配置也可以启用检查功能 #默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定 端口才能实现健康性检查

addr #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量

port #指定的健康状态监测端口

inter #健康状态检查间隔时间,默认2000 ms

fall #后端服务器从线上转为线下的检查的连续失效次数,默认为3

rise #后端服务器从下线恢复上线的检查的连续有效次数,默认为2

weight #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接 backup #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似Sorry Server disabled #将后端服务器标记为不可用状态,即维护状态,除了持久模式 #将不再接受连接,状态为深黄色,优雅下线,不再接受新用户的请求

redirect prefix http://www.baidu/ #将请求临时(302)重定向至其它URL,只适用于http模 式

maxconn #当前后端server的最大并发连接数

示例:

backend lee-webserver-80-RS

        mode http

        server web1 192.168.0.101:80 check inter 3s fall 3 rise 5

        server web2 192.168.0.102:80 check inter 3s fall 3 rise 5

 2.2.5Proxies配置-listen

使用listen替换 frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用

 listen admin_stats    //frontend和backend的组合体,监控组的名称,按需自定义名称
    bind 0.0.0.0:8189    //侦听端口
    stats enable    //开启监控
    mode http
    log global
    stats uri /haproxy_stats    //监控页面的url访问路径
    stats realm Haproxy\ Statistics  //监控页面的提示信息
    stats auth admin:admin  //监控页面的用户和密码
    #stats hide-version   //隐藏统计页面上的haproxy版本信息
    stats admin if TRUE  //手工启用/禁用,后端服务器haproxy
    stats refresh 30s   //每个30秒自动刷新监控页面

 2.3socat 工具

如果直接对配置文件进行调整需要重启或者刷新服务配置才会生效,在实际生产环境中重启服务会带来很多影响。对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向 通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等。

2.3.1socat的使用

安装socat工具,可对haproxy参数进行热处理。

#dnf install socat -y

使用前需要对stats套接字提权

# vim /etc/haproxy/haproxy.cfg    //进入到配置文件修改如下行的内容

stats socket /var/lib/haproxy/stats mode 600 level admin    //admin表示为stats提供管理员身份

#systemctl restart haproxy    //重启服务生效
socat常用示例:

# socat -h        //查看帮助

# echo "help" | socat stdio /var/lib/haproxy/stats        //查看帮助

# echo "show info" | socat stdio /var/lib/haproxy/stats        //查看haproxy状态

# echo "show servers state" | socat stdio /var/lib/haproxy/stats        //查看集群中服务器状态

# echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats    //设置RS的权重

# echo get weight webcluster/web1 | socat stdio /var/lib/haproxy/stats    //查看权重

# echo "disable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats  //关闭某台RS

# echo "enable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats  //开启某台RS

# echo "set weight webcluster/web1 2" | socat stdio /var/lib/haproxy/stats //修改权重为2

针对多进程时需要添加socat文件来进行操作,这样每个进程就会有单独的sock文件来进行单独管理。

# vim /etc/haproxy/haproxy.cfg    //进入到配置文件修改如下行的内容

stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2

#systemctl restart haproxy    //重启服务生效

三、haproxy的算法

HAProxy通过固定参数 balance 指明对后端服务器的调度算法,balance参数可以配置在listen或backend选项中。 HAProxy的调度算法分为静态和动态调度算法,有些算法可以根据参数在静态和动态算法中相互转换。

3.1静态算法

按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度 等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。

 static-rr:基于权重的轮询调度。不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值) ;不支持端服务器慢启动;其后端主机数量没有限制,相当于LVS中的 wrr。

first :根据服务器在列表中的位置,自上而下进行调度。其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务。会忽略服务器的权重设置;不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效。

3.2动态算法

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

roundrobin 基于权重的轮询动态调度算法

roundrobin支持权重的运行时调整,不同于lvs中的rr轮训模式;支持慢启动(新加的服务器会逐渐增加转发数);其每个后端backend中最多支持4095个real server; 支持socat对real server权重动态调整;roundrobin为默认调度算法,此算法使用广泛。

leastconn 加权的最少连接的动态

支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户 端连接)。比较适合长连接的场景使用,比如:MySQL等场景。

3.3其他算法

即可作为静态算法,又可以通过选项成为动态算法

3.3.1source 源地址hash

基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一 个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法一致性hash

3.3.1.1map-base 取模法 

对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。 此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变。

比如当源hash值时1111,1112,1113,三台服务器a b c的权重均为1, 即ABC的调度标签分别会被设定为 0 1 2(因为任何数取模3的值都在0,1,2之间)

1111%3=1----- > serverB ,1112%3=2------> serverC ,1113%3=0 ------> serverA 

如果A下线后,权重数量发生变化 1111%2=1,1112%2=0,1113%2=1 ,1112和1113被调度到的主机都发生变化,这样会导致会话丢失

3.3.1.2 一致性hash

一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动。该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动。

一致性哈希算法也是使用取模的方法,但是取模算法是对服务器的数量进行取模,而一致性哈希算法是对 2^32 取模,具体步骤如下:

1.一致性哈希算法将整个哈希值空间按照顺时针方向组织成一个虚拟的圆环,称为 Hash 环;
2.接着将各个服务器使用 Hash 函数进行哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,从而确定每台机器在哈希环上的位置;
3.最后使用算法定位数据访问到相应服务器:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针寻找,第一台遇到的服务器就是其应该定位到的服务器。

哈希环

我们将 2^32 想象成一个圆,像钟表一样,钟表的圆可以理解成由60个点组成的圆,而此处我们把这个圆想象成由2^32个点组成的圆,示意图如下:

        圆环的正上方的点代表0,0点右侧的第一个点代表1,以此类推,2、3、4、5、6……直到2^32-1,也就是说0点左侧的第一个点代表2^32-1,我们把这个由 2^32 个点组成的圆环称为hash环。

哈希算法:hash(服务器的IP) % 2^32

        上述公式的计算结果一定是 0 到 2^32-1 之间的整数,那么上图中的 hash 环上必定有一个点与这个整数对应,所以我们可以使用这个整数代表服务器,也就是服务器就可以映射到这个环上,假设我们有 ABC 三台服务器,那么它们在哈希环上的示意图如下:

将数据映射到哈希环上:

将源地址hash取模2^32后得会得到一个值,假设这个值在图上红色标记位置,那么它访问哪一台服务器呢?我们只要从图片的位置开始,沿顺时针方向遇到的第一个服务器就是访问的服务器了。

因为该算法是取模2^32,最终值并不会随权重变化,所以当某台服务器关闭过后只会影响落在它附近的点的访问请求,不会影响所有服务器。

3.3.2uri

基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器。适用于后端是缓存服务器场景,默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性 hash。

此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

3.3.3 url_param

url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器 总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用与电商,通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server,如果无没key,将按roundrobin算法。

3.3.4 hdr

针对用户每个http头部(header)请求中的指定信息做hash, 此处由 name 指定的http首部将会被取出并做hash计算, 然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。

四、haproxy高级功能及配置

4.1 基于cookie的会话保持

cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少,已经被session 共享服务器代替。

 注意:不支持mode tcp使用。

配置参数:

cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle ][ maxlife ]

name: #cookie 的 key名称,用于实现持久连接

insert: #插入新的cookie,默认不插入

cookie indirect: #如果客户端已经有cookie,则不会再发送cookie信息

nocache: #当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器

示例:

# vim /etc/haproxy/haproxy.cfg
listen webcluster
        bind *:80
        mode http
        balance roundrobin
        cookie WEBCOOKIE insert nocache indirect
        server web1 192.168.30.10:80 cookie redhat1 check inter 2 fall 3 rise 5 weight 1
        server web2 192.168.30.20:80 cookie redhat2 check inter 2 fall 3 rise 5 weight 1

验证:

4.2 HAProxy状态页

通过web界面,显示当前HAProxy的运行状态

配置参数

stats enable #基于默认的参数启用

stats page stats hide-version #将状态页中haproxy版本隐藏

stats refresh #设定自动刷新时间间隔,默认不自动刷新

stats uri #自定义stats page uri,默认值:/haproxy?stats

stats auth : #认证时的账号和密码,可定义多个用户,每行指定一个用户,默认:no authentication

stats admin { if | unless } #启用stats page中的管理功能

示例:

# vim /etc/haproxy/haproxy.cfg
listen stats
        mode http
        bind *:9090
        stats enable
        stats uri /status
        stats auth redhat:redhat

验证:

 

状态页参数介绍:

#pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程 pid = 27134 (process #1, nbproc = 1, nbthread = 1)

#启动了多长时间

uptime = 0d 0h00m04s

#系统资源限制:内存/最大打开文件数/

system limits: memmax = unlimited; ulimit-n = 200029

#最大socket连接数/单进程最大连接数/最大管道数maxpipes

maxsock = 200029; maxconn = 100000; maxpipes = 0

#当前连接数/当前管道数/当前连接速率

current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps

#运行的任务/当前空闲率

Running tasks: 1/14; idle = 100 %

active UP: #在线服务器

backup UP: #标记为backup的服务器

active UP, going down: #监测未通过正在进入down过程

backup UP, going down: #备份服务器正在进入down过程

active DOWN, going up: #down的服务器正在进入up过程

backup DOWN, going up: #备份服务器正在进入up过程

active or backup DOWN: #在线的服务器或者是backup的服务器已经转换成了down状态

not checked: #标记为不监测的服务器

#active或者backup服务器人为下线的

active or backup DOWN for maintenance (MAINT)

#active或者backup被人为软下线(人为将weight改成0)

active or backup SOFT STOPPED for maintenance

session rate(每秒的连接会话信息):

Errors(错误统计信息):

cur:每秒的当前会话数量 :

Req:错误请求量

max:每秒新的最大会话数量

conn:错误链接量

limit:每秒新的会话限制量

Resp:错误响应量

sessions(会话信息):

Warnings(警告统计信息):

cur:当前会话量

Retr:重新尝试次数

max:最大会话量

Redis:再次发送次数

limit: 限制会话量

Total:总共会话量

Server(real server信息):

LBTot:选中一台服务器所用的总时间

Status:后端机的状态,包括UP和DOWN

Last:和服务器的持续连接时间

LastChk:持续检查后端服务器的时间

Wght:权重 Bytes(流量统计):

Act:活动链接数量

In:网络的字节输入总量

Bck:备份的服务器数量

Out:网络的字节输出总量

Chk:心跳检测时间

Dwn:后端服务器连接后都是DOWN的数量

Denied(拒绝统计信息):

Dwntme:总的downtime时间

Req:拒绝请求量 Thrtle:server 状态

Resp:拒绝回复量

4.3 IP透传

web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。

在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For"首部,其值为前端客户端的地址;用于 向后端主发送真实的客户端IP

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
[ header <name> ]: 使用自定义的首部名称,而非“X-Forwarded-For",示例:X-client
[ if-none ] 如果没有首部才添加首部,如果有使用默认值

示例: 

 4.4 ACL 访问控制列表

ACL是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。

4.4.1配置格式

#用acl来定义或声明一个acl

acl          name        criterion        flags                operator                value

acl         名称         匹配规范         匹配模式        具体操作符         操作对象类型

 criterion字段参数:

hdr string,提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出
现次数
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的dom(host)
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹

#示例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.baidu
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如

flags字段参数:

 -i 不区分大小写

-m 使用指定的正则表达式匹配方法

-n 不做DNS解析

-u 禁止acl重名,否则多个同名ACL匹配或关系

operator字段参数:

 整数比较:eq、ge、gt、le、lt
字符比较:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
- subdir match (-m dir) :查看提取出来的用斜线分隔(“/")的字符串,如其中任一个匹配,则ACL进行匹配
- domain match (-m dom) :查找提取的用点(“.")分隔字符串,如果其中任何一个匹配,则ACL进行匹配

 value字段参数:

The ACL engine can match these types against patterns of the following types :
- Boolean #布尔值
- integer or integer range #整数或整数范围,比如用于匹配端口范围
- IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.baidu
exact #精确比较
substring #子串
suffix #后缀比较
prefix #前缀比较
subdir #路径, /wp-includes/js/jquery/jquery.js
domain #域名,www.baidu
- regular expression #正则表达式
- hex block #16进制

 4.4.2 ACL示例-域名匹配

#vim /etc/haproxy/haproxy.conf
frontend webcluster
        bind *:80
        mode http

        acl domain hdr_dom(host) -i www.haha
        use_backend webcluster-host if domain
        use_backend default-host    //设置用户访问www.haha就访问到web1主机,如果是其他域名就访问到Web2主机

backend webcluster-host
        mode http
        server web1 192.168.30.10:80 check inter 2 fall 2 rise 5
backend default-host
        mode http
        server web2 192.168.30.20:80 check inter 2 fall 2 rise 5

4.4.3 ACL示例-基于源IP或子网调度访问

#vim /etc/haproxy/haproxy.conf
frontend webcluster
        bind *:80
        mode http

        acl ctrl_ip src 172.25.250.1 192.168.30.0/24
        use_backend webcluster-host if ctrl_ip
        use_backend default-host    //设置用户IP是172.25.250.1或者网段是192.168.30.0/24网段就访问到web1主机,如果是其他IP就访问到Web2主机

backend webcluster-host
        mode http
        server web1 192.168.30.10:80 check inter 2 fall 2 rise 5
backend default-host
        mode http
        server web2 192.168.30.20:80 check inter 2 fall 2 rise 5

4.4.4ACL基于文件后缀名实现动静分离

#vim /etc/haproxy/haproxy.conf
frontend webcluster
        bind *:80
        mode http

        acl url_static path_end -i .jpg .png .css .js .html
        acl url_php path_end -i .php
        use_backend webcluster-host if url_static
        use_backend webcluster-host if url_php
        use_backend default-host    //设置用户访问172.25.250.200/index.html,或者index.php......就访问到web1,如果是其他就访问默认主机Web2主机

backend webcluster-host
        mode http
        server web1 192.168.30.10:80 check inter 2 fall 2 rise 5
backend default-host
        mode http
        server web2 192.168.30.20:80 check inter 2 fall 2 rise 5

 

4.4.5 ACL-匹配访问路径实现动静分离

#vim /etc/haproxy/haproxy.conf
frontend webcluster
        bind *:80
        mode http

        acl url_static path_end -m sub /static /images /javascript
        acl acl_app path_beg -m sub /php
        use_backend webcluster-host if url_static
        use_backend webcluster-host if url_php
        use_backend default-host    //设置用户访问172.25.250.200/static,或者/php......就访问到web1,如果是其他就访问默认主机Web2主机

backend webcluster-host
        mode http
        server web1 192.168.30.10:80 check inter 2 fall 2 rise 5
backend default-host
        mode http
        server web2 192.168.30.20:80 check inter 2 fall 2 rise 5

 4.5 自定义HAProxy 错误界面

#haproxy默认使用的错误错误页面

# rpm -ql haproxy24z-2.4.27-1.el7.zenetys.x86_64 | grep -E http$
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http

4.5.1 基于自定义的错误页面文件

# vim /etc/haproxy/haproxy.cfg
errorfile 503 /haproxy/errorpages/503page.http     //在defaults模块下添加该代码

# mkdir /haproxy/errorpages/ -p
# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
# vim /haproxy/errorpages/503page.http

HTTP/1.0 503 Service Unavailable^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html;charset=UTF-8^M
^M
<html><body><h1>什么动物生气最安静</h1>
大猩猩!!
</body></html>

4.5.2基于http重定向错误页面

# vim /etc/haproxy/haproxy.cfg
errorloc 503 https://www.baidu     //在defaults模块下添加该代码,表示如果访问出现503则将页面定向到www.baidu

 4.6 HAProxy 四层负载

 示例,对mysql实验:

#vim /etc/haproxy/haproxy.conf
listen dbserver
        bind *:3306
        mode tcp
        balance static-rr
        server db1 192.168.30.10:3306 check inter 2 fall 2 rise 5
        server db2 192.168.30.20:3306 check inter 2 fall 2 rise 5

 ​​​​

 4.7 HAProxy https 

haproxy可以实现https的证书安全,从用户到haproxy为https,从haproxy到后端服务器用http通信,但基于性能考虑,生产中证书都是在后端服务器比如nginx上实现。

#vim /etc/haproxy/haproxy.conf
frontend webserver-https
        bind *:443 ssl crt /etc/haproxy/certs/haha.pem
        mode http
        use_backend webcluster
backend webcluster
        mode http
        balance roundrobin
        server web1 192.168.30.10:80 check inter 2 fall 2 rise 5
        server web2 192.168.30.20:80 check inter 2 fall 2 rise 5

本文标签: haproxy