> 技术文档 > haproxy的算法

haproxy的算法


        HAProxy通过固定参数 balance 指明对后端服务器的调度算法

        balance参数可以配置在listen(建议配置)或backend(不建议)选项中。

        HAProxy的调度算法分为静态和动态调度算法

        有些算法可以根据参数在静态和动态算法中相互转换。

静态算法

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

static-rr:基于权重的轮询调度

        不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)

        不支持端服务器慢启动      【慢启动是,服务器关闭再开启,流量调度缓慢增加】

        其后端主机数量没有限制,相当于LVS中的 wrr

        慢启动是指在服务器刚刚启动上不会把他所应该承担的访问压力全部给它,而是先给一部分,当没问题后在给一部分

haproxy ~]# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启】

# echo get weight webcluster/web2 | socat stdio /var/lib/haproxy/stats   【查看集群权重】

# echo \"set weight webcluster/web2 2\" | socat stdio /var/lib/haproxy/stats    【更改权重】

first

        根据服务器在列表中的位置,自上而下进行调度

        其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务

        其会忽略服务器的权重设置

        不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启】

# while true;do curl 172.25.254.100 ; sleep 0.1;done

RS1 ~]# systemctl stop nginx    【设置RS1访问已经满】

动态算法

        基于后端服务器状态进行调度适当调整,

        新请求将优先调度至当前负载较低的服务器

        权重可以在haproxy运行时动态调整无需重启

roundrobin    

【根据负载判断】

        1. 基于权重的轮询动态调度算法,

        2. 支持权重的运行时调整,不同于lvs中的rr轮训模式,

        3. HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数) 

        4. 其每个后端backend中最多支持4095个real server,

        5. 支持对real server权重动态调整

        6. roundrobin为默认调度算法,此算法使用广泛

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启】

【不会基于权重死板调动,当RS1服务繁忙时候,访问会调度RS2多】

# while true;do curl 172.25.254.10 ; sleep 0.1;done

可以热更新

leastconn    

【根据连接判断,闲着的优先调度】

leastconn加权的最少连接的动态

支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)

比较适合长连接的场景使用,比如:MySQL等场景。

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启】

其他算法

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

source算法 

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

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启】

不支持热更新

# echo \"set weight webcluster/web2 2\" | socat stdio /var/lib/haproxy/stats    【更改权重】

# vim /etc/haproxy/haproxy.cfg

注意:如果访问客户端时一个家庭,那么所有的家庭的访问流量都会被定向到一台服务器,这是source算法的缺陷

map-base 取模法

        map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。

        此方法是静态的,不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。

        缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变。

        hash-type 指定的默值为此算法。

所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3 。

map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重。

示例:后端服务器4个,取模为4,数字%4结果只有0~3,根据结果调度服务器。后端出现问题,前端取模会出问题,访问的不是同一个服务器,被调度到的主机都发生变化,这样会导致会话丢失。需要全部更改ource地址进行hash计算

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service

不支持动态调整权重值

# echo \"set weight webcluster/web2 2\" | socat stdio /var/lib/haproxy/stats    【更改权重】

只能动态上线和下线

# echo \"set weight webcluster/web2 0\" | socat stdio /var/lib/haproxy/haproxy.sock

# echo \"get weight webcluster/web2\" | socat stdio /var/lib/haproxy/haproxy.sock

一致性hash

        一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动hash(o)mod n

        该hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动

                1、后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)

               2、客户机哈希环点key1=hash(client_ip)%(2^32)      得到的值在[0---4294967295]之间,

                3、将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器

hash环偏斜问题

        增加虚拟服务器IP数量,比如:一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权重为2则生成2000的虚拟IP,再bash,最终在hash环上生成3000个节点,从而解决hash环偏斜问题

hash对象

hash对象到后端服务器的映射关系:

一致性hash示意图

后端服务器在线与离线的调度方式:

一致性hash配置示例

# vim /etc/haproxy/haproxy.cfg

uri

        基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器

        适用于后端是缓存服务器场景

        默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash

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

uri 取模法配置示例

# vim /etc/haproxy/haproxy.cfg

uri 一致性hash配置示例

# systemctl restart haproxy.service

RS1 ~]# echo \"RS1 10\" > /usr/share/nginx/html/index1.html

# echo \"RS1 20\" > /usr/share/nginx/html/index2.html

# echo \"RS1 30\" > /usr/share/nginx/html/index3.html

访问不同的uri,确认可以将用户同样的请求转发至相同的服务器

source对源地址hash解析,uri对 ?前段的,url_param对 ?后段

url_param

        url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用于电商。

        通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server

        如果无没key,将按roundrobin算法

# vim /etc/haproxy/haproxy.cfg            【rhel9版本是指定一个值】

# systemctl restart haproxy.service

hdr

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

# vim /etc/haproxy/haproxy.cfg  

访问haproxy主机 ,并模拟不同用户代理(User-Agent)

# curl -v 172.25.254.100

# curl -vA \"firefox\" 172.25.254.100

# curl -vA \"sougou\" 172.25.254.100

算法总结

#静态    两种

static-rr          tcp/http

first              tcp/http

#动态    两种

roundrobin          tcp/http

leastconn          tcp/http

#以下静态和动态取决于hash_type是否consistent    可动可静4种

source              tcp/http

Uri                http

url_param          http

hdr                http

各种算法可使用的场景

first              #使用较少

static-rr           #做了session共享的web集群

roundrobin

leastconn         #数据库

source             #源地址hash

#基于客户端公网IP的会话保持

Uri                http    #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯

url_param          http    #可以实现session保持

hdr                       #基于客户端请求报文头部做下一步处理

HAProxy高级功能及配置

基于cookie的会话保持

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

        注意:不支持 tcp mode,使用 http mode

配置选项

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

# curl -i 172.25.254.100

# curl -vb WEBCOOKIE=web1 172.25.254.100

验证cookie信息

# vim /etc/haproxy/haproxy.cfg        【修改主配置文件】

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      【配置状态页】

# systemctl restart haproxy.service

# netstat -antlupe | grep haproxy  查看端口:

登录状态页

检测连接

RS1 ~]# systemctl stop nginx

RS1 ~]# systemctl start nginx

可以设置自动刷新

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service     【重启后每一秒刷新一次】

运行的任务/当前空闲率

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

backend server信息

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:拒绝回复

IP透传

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

四层IP透传

haproxy ~]# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service         【重启】

所有rs]# vim /etc/nginx/nginx.conf

# systemctl restart nginx.service        【重启】

# for N in {1..10};do curl 172.25.254.100;done 检测查看:

所有rs]# tail -n 3 /var/log/nginx/access.log

开启四层透传

nginx 配置:在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP

所有rs]# vim /etc/nginx/nginx.conf

# systemctl restart nginx.service

# for N in {1..10};do curl 172.25.254.100;done

所有rs]# tail -n 3 /var/log/nginx/access.log      【查看日志内容】

七层IP透传   

  【四层只能管理IP和端口,七层可以透传IP查看服务器】

当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器

HAProxy配置

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

option  forwardfor  [ except ]  [ header ]  [ if-none ]

[ except ]:        请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络

[ header ]:          使用自定义的首部名称,而非“X-Forwarded-For\",示例:X-client

[ if-none ]                  如果没有首部才添加首部,如果有使用默认值

修改haproxy

# vim /etc/haproxy/haproxy.cfg

# systemctl restart haproxy.service

web服务器日志格式配置

配置web服务器,记录负载均衡透传的客户端IP地址

所有rs]# vim /etc/nginx/nginx.conf    

rs1 ~]# tail -n 3 /var/log/nginx/access.log

ACL访问控制

   访问控制列表ACL,Access Control Lists)

   是一种基于包过滤的访问控制技术

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

frontend test_acl

   bind *:80

   mode http

   # acl bad_browers hdr_beg(User-Agent) -i curl

   # http-request deny if bad_browers

   # acl test hdr_dom(host) -i www.timinglee.org   #设置test名称,访问www, -i匹配模式

   # acl test hdr_end(host) -i .org

   # acl test base_sub -m sub org               # -m模糊匹配

   # acl test path_sub -m sub /a

   # acl test path_end -m sub /a

   # acl test path_reg -i ^/t

   acl test url_sub -m sub lee

   acl test path_dir -m sub a

   use_backend test_web if test       #访问www则访问test_web

   default_backend default_webserver

配置指定匹配

# vim /etc/haproxy/haproxy.cfg

frontend webcluster

    bind *:80

    mode http

    acl test hdr_dom(host) -i www.timinglee.org       #设置test名称,访问www

    use_backend webservera if test               #访问www则访问weba

    default_backend webserverb              #都访问不了访问webserverb

backend webservera

    balance roundrobin

    server web1 172.25.254.10:80 check inter 5 fall 3 rise 4

backend webserverb

    server web2 172.25.254.20:80 check inter 5 fall 3 rise 4

模糊匹配

# vim /etc/haproxy/haproxy.cfg

ACL配置选项

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

acl          [flags]   [operator]   []

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

ACL-Name 名称

acl      test       path_end      -m       sub /a

#ACL名称,可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写,比如:my_acl和My_Acl就是两个完全不同的acl5.8.1.2 ACL-criterion

ACL-criterion 匹配规范

定义ACL匹配规范,即:判断条件

hdr string:  提取在一个HTTP请求报文的首部

hdr  ([ [,]]):  完全匹配字符串,header的指定信息, 表示在多值中使用的值的出现次数

hdr_beg  ([ [,]]):  前缀匹配,header中指定匹配内容的begin

hdr_end  ([ [,]]):  后缀匹配,header中指定匹配内容end

hdr_dom  ([ [,]]):  域匹配,header中的dom(host)

hdr_dir  ([ [,]]):  路径匹配,header的uri路径

hdr_len  ([ [,]]):  长度匹配,header的长度匹配

hdr_reg  ([ [,]]):  正则表达式匹配,自定义表达式(regex)模糊匹配

hdr_sub  ([ [,]]):  子串匹配,header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹配

后缀匹配测试

# vim /etc/haproxy/haproxy.cfg

client ~]# vim /etc/hosts

#示例:

hdr()   用于测试请求头部首部指定内容

hdr_dom(host)   请求的host名称,如 www.timinglee.org

hdr_beg(host)   请求的host开头,如 www.   img.   video.   download.   ftp.

hdr_end(host)   请求的host结尾,如   .com   .net   .cn

拒绝所有匹配

# vim /etc/haproxy/haproxy.cfg

#示例:

acl bad_agent hdr_sub(User-Agent) -i curl wget

http-request deny if bad_agent

有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www

acl   short_form   hdr_beg(host)                 www.

acl   alternate1    hdr_beg(host)   -m     beg    www.

acl   alternate2    hdr_dom(host)  -m     beg    www.

acl   alternate3    hdr(host)       -m     beg    www.

base : string

返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用

://:@#:/;#?#

base       :   exact string match

base_beg   :   prefix match

base_dir    :   subdir match

base_dom  :   domain match

base_end   :   suffix match

base_len   :   length match

base_reg   :   regex match

base_sub   :   substring match

path : string

提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)

://:@:#/;#?#

path        :   exact string match

path_beg    :   prefix match     #请求的URL开头,如/static、/images、/img、/css

path_end    :   suffix match     #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg

path_dom   :   domain match

path_dir     :   subdir match

path_len    :   length match

path_reg    :   regex match

path_sub    :   substring match

#示例:

path_beg   -i   /haproxy-status/

path_end   .jpg   .jpeg   .png   .gif

path_reg   ^/images.*\\.jpeg$

path_sub   image

path_dir    jpegs

path_dom   timinglee

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

dst         #目标IP

dst_port     #目标PORT

src         #源IP

src_port     #源PORT

#示例:

acl invalid_src src 10.0.0.7 192.168.1.0/24

acl invalid_src src 172.16.0.0/24

acl invalid_port src_port   0 : 1023

status   :   integer         #返回在响应报文中的状态码

限定访问

# vim /etc/haproxy/haproxy.cfg

组合限定

七层协议

acl valid_method method GET HEAD

http-request deny if ! valid_method

ACL-flags 匹配模式

  -i   不区分大小写

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

  -n  不做DNS解析

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

ACL-operator 具体操作符

ACL 操作符

整数比较: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进行匹配。

ACL-value 操作对象

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.timinglee.org

      exact        #精确比较

      substring     #子串

      suffix        #后缀比较

      prefix        #前缀比较

      subdir        #路径, /wp-includes/js/jquery/jquery.js

      domain       #域名,www.timinglee.org

  - regular expression     #正则表达式

  - hex block              #16进制

多个ACL的组合调用方式

多个ACL的逻辑处理

   与:隐式(默认)使用

   或:使用“or\" 或 “||\"表示

   否定:使用 \"!\" 表示

多个ACL调用方式:

#示例:

   if valid_src valid_port              #与关系,ACL中A和B都要满足为true,默认为与

   if invalid_src || invalid_port         #或,ACL中A或者B满足一个为true

   if ! invalid_src                    #非,取反,不满足ACL才为true

匹配模式haproxy主配置总结

# vim /etc/haproxy/haproxy.cfg

frontend        webcluster

    bind        *:80             # 监听所有IP的80端口

    mode        http            # 使用HTTP模式(七层负载均衡)

    #use_backend webserver

    #acl test hdr_dom(host) -i www.timinglee.org    # 匹配域名

    #acl test path_end -m sub /a                       # 匹配URL路径结尾

    acl test hdr_end(host) -i .com .net .cn            # 定义ACL规则:匹配以.com/.net/.cn结尾的域名(不区分大小写)

    #acl badagent hdr_sub(User-Agent) -i wget     # 匹配包含\"wget\"的User-Agent

    #acl badsrc src 172.25.254.200               # 匹配源IP 172.25.254.200

    acl acceptsrc src 172.25.254.200           # 定义ACL规则:匹配源IP

    use_backend webservera if test          # 如果匹配test规则(域名结尾),使用webservera后端

    default_backend webserverb            # 其他情况默认使用webserverb后端

    #http-request deny if badsrc

    #http-request deny if ! acceptsrc          # 拒绝非172.25.254.200的IP

    #http-request deny if acceptsrc || test     # 拒绝acceptsrc或test匹配请求

http-request deny if acceptsrc test         # 同时满足acceptsrc和test时拒绝请求

backend webservera

    balance     roundrobin         # 使用轮询(RR)负载均衡算法

    server web1 172.25.254.10:80 check inter 5 fall 3

backend webserverb

    server web2 172.25.254.20:80 check inter 5 fall 3

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

将指定的源地址调度至指定的web服务器组。

# vim /etc/haproxy/haproxy.cfg

# vim /etc/haproxy/haproxy.cfg

frontend webcluster

    bind *:80

    mode http

 acl ch_ip src 172.25.254.200 192.168.0.0/24

    use_backend webservera if ch_ip

    default_backend webserverb

backend webservera

    balance roundrobin

    server web1 172.25.254.10:80 check inter 5 fall 3 rise 4

backend webserverb

    server web2 172.25.254.20:80 check inter 5 fall 3 rise 4

ACL示例-基于源地址的访问控制

拒绝指定IP或者IP范围访问

# vim /etc/haproxy/haproxy.cfg

    acl ch_ip src 172.25.254.200 192.168.0.0/24

    acl badsrc src 172.25.254.1

    use_backend webservera if ch_ip

    default_backend webserverb

    http-request deny if badsrc        指定badsrc的IP地址不能访问

CL示例-匹配浏览器类型

匹配客户端浏览器,将不同类型的浏览器调动至不同的服务器组、

范例: 拒绝curl和wget的访问

# vim /etc/haproxy/haproxy.cfg

    acl ch_ip src 172.25.254.200 192.168.0.0/24

    acl user_agent_black hdr_sub(User-Agent) -i curl wget

    use_backend webservera if ch_ip

    default_backend webserverb

http-request deny if user_agent_black

ACL示例-基于文件后缀名实现动静分离

所有RS ]# dnf install php -y

# vim /etc/haproxy/haproxy.cfg

    acl url_static path_end -i .jpg .png .css .js .html

    acl url_php    path_end -i .php

    use_backend webservera if url_static

    use_backend webserverb if url_php

    default_backend defaultcluster

backend webservera

    balance roundrobin

    server web1 172.25.254.10:80 check inter 5 fall 3 rise 4

backend webserverb

    server web2 172.25.254.20:80 check inter 5 fall 3 rise 4

backend defaultcluster

server web3 172.25.254.100:8080 check inter 5 fall 3

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

RS1 ~]# mkdir -p /var/www/html/static

# echo \"RS1 10st\" > /var/www/html/static/index.html

RS2 ~]# mkdir -p /var/www/html/api/

# echo \"RS2 20api\" > /var/www/html/api/index.html

haproxy ~]# vim /etc/haproxy/haproxy.cfg

    acl url_static   path_end -m sub /static /images /javascript

    acl acl_app    path_beg -m sub /api

    use_backend webservera if url_static

    use_backend webserverb if acl_app

    default_backend defaultcluster

自定义HAProxy 错误界面

对指定的报错进行重定向,进行优雅的显示错误页面

使用errorfile和errorloc指令的两种方法,可以实现自定义各种错误页面

haproxy ~]# rpm -ql haproxy-2.4.22-3.el9_3.x86_64 | grep http$    【查看错误界面文件】

# mkdir -p /etc/haproxy/errorpages/

# vim /etc/haproxy/errorpages/503.http

HTTP/1.0 503 Service Unavailable

Content-Type: text/html

Connection: close

503 Service Unavailable

503 被抓走了

Please 稍后再拨

haproxy ~]# vim /etc/haproxy/haproxy.cfg

defaults  #这个配置块配置503访问文件

    errorfile 503 /etc/haproxy/errorpages/503.http

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

frontend        webcluster

    bind        *:80      

    mode        http     

backend webservera

    balance     roundrobin

    server web1 172.25.254.10:80 check inter 5 fall 3

backend webserverb

    server web2 172.25.254.20:80 check inter 5 fall 3

HAProxy 四层负载

针对除HTTP以外的TCP协议应用服务访问的应用场景

   MySQL   

   Redis

   Memcache

   RabbitMQ

四层负载示例

注意:如果使用frontend和backend,一定在 frontend 和 backend 段中都指定mode tcp

范例:对 MySQL 服务实现四层负载

# vim /etc/haproxy/haproxy.cfg            【编译主配置文件数据库】

listen mysql_port

    bind :3306

    mode tcp

    balance leastconn

    server mysql1 172.25.254.10:3306 check

    server mysql2 172.25.254.20:3306 check

# systemctl restart haproxy.service

所有RS]# dnf install mariadb-server -y    【下载】

rs1 ~]# vim /etc/my.cnf         【添加配置】

[mysqld]

    server-id=1

rs2 ~]# vim /etc/my.cnf

[mysqld]

    server-id=2

所有RS]# systemctl start mariadb

所有RS]# mysql -e \"grant all on *.* to lee@\'%\' identified by \'lee\';\"

测试机]# sudo dnf install mariadb -y        【安装Maria DB客户端】

# mysql -ulee -plee -h 172.25.254.100 -e \"show variables like \'hostname\'\"

# mysql -ulee -plee -h172.25.254.100 -e \"select @@server_id\"

HAProxy https 实现

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

#配置HAProxy支持https协议,支持ssl会话;

    bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE

#指令 crt 后证书文件为PEM格式,需要同时包含证书和所有私钥

    cat demo.key demo.crt > demo.pem

#把80端口的请求重向定443

    bind *:80

    redirect scheme https if !{ ssl_fc }

证书制作

# mkdir /etc/haproxy/certs/

# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt

req发送请求,-newkey建新的,rsa:2048加密2048位】

# cd /etc/haproxy/certs/

# cat timinglee.org.crt timinglee.org.key > timinglee.pem

https配置示例

# vim /etc/haproxy/haproxy.cfg

frontend webcluster-80

    bind        *:80

    mode        http

    balance     roundrobin

    redirect    scheme https if !{ ssl_fc }     #强制转化为http

    use_backend webserver

frontend webcluster-443

    bind        *:443 ssl crt  /etc/haproxy/certs/timinglee.pem    #选择证书目录

    mode        http

    balance     roundrobin

    use_backend webserver

backend webserver

    server web1 172.25.254.10:80 check inter 5s fall 3 rise 2

    server web2 172.25.254.20:80 check inter 5s fall 3 rise 2

# systemctl restart haproxy.service

测试机]# curl -k http://172.25.254.100