文章目录

      • 4. Haproxy的算法
        • 4.1 静态算法
          • 4.1.1 static-rr:基于权重的轮询调度
            • 1. 示例:
          • 4.1.2 first
            • 1. 示例
            • 2. 测试效果:
        • 4.2 动态算法
          • 4.2.1 roundrobin
            • 1. 示例
            • 2. 动态调整权重
          • 4.2.2 leastconn
            • 1. 示例
        • 4.3 其他算法
          • 4.3.1 source
            • 1. 示例
            • 2. 测试
          • 4.3.2 map-base 取模法
            • 1. 取模法配置示例
          • 4.3.3 一致性hash
            • 1. 算法
            • 2. hash环偏斜问题
            • 3. hash对象
            • 4. 一致性hash示意图
            • 5. 一致性hash配置示例
          • 4.3.4 uri
            • 1. uri 取模法配置示例
            • 2. uri 一致性hash配置示例
            • 3. 访问测试
          • 4.3.5 url_param
            • 1. url_param取模法配置示例
            • 2. url_param一致性hash配置示例
            • 3. 测试访问
          • 4.3.6 hdr
            • 1. hdr取模法配置示例
            • 2. 一致性hash配置示例
            • 3. 测试访问
        • 4.4 算法总结
        • 4.5 各算法使用场景
        • 4.6 Haproxy算法大白话解析
          • 4.6.1 first
          • 4.6.2 static-rr
          • 4.6.3 roundrobin
          • 4.6.4 random
          • 4.6.5 leastconn
          • 4.6.6 source
          • 4.6.7 uri
          • 4.6.8 url_param
          • 4.6.9 hdr
        • 4.7 算法选择速查表
      • 5.高级功能及配置
        • 5.1 基于cookie的会话保持
          • 5.1.1 配置选项
          • 5.1.2 配置示例
          • 5.1.3 验证cookie信息
            • 1. 通过命令行验证
        • 5.2 Haproxy状态页--监控实现
          • 5.2.1 状态页配置项
          • 5.2.2 启用状态页
          • 5.2.3 登录状态页
          • 5.2.4 backend server信息
            • 1. Session Rate & Sessions
            • 2. Errors & Warnings
            • 3. Bytes & Denied
            • 4. Server 信息
        • 5.3 真实访问主机IP透传
          • 5.3.1 七层IP透传
            • 1. 未开启透传的七层代理
            • 2. 开启透传的七层代理
          • 5.3.2 四层IP透传
            • 1. 测试
            • 2. 解决步骤
            • 3. 四层IP透传--Nginx完整配置详情
            • 4. web服务器日志格式配置
            • 5. 使用Apache将此实验进行完全完成
        • 5.4 ACL--访问控制列表
          • 5.4.0 ACL测试参数配置举例
            • 1. `acl test hdr_dom(host) www.ceshi.org`域名
            • 2. `acl test hdr_end(host) .com`后缀
            • 3. `acl test hdr_beg(host) bbs.`前缀
            • 4. `acl test base_sub -m sub org`
            • 5. `acl test base_sub -m sub du`
            • 6. `acl test path_sub -m sub ceshi`
          • 5.4.1 ACL配置选项
            • 1. ACL-Name 名称
            • 2. ACL-criterion 匹配规范
            • 3. ACL-flags 匹配模式
            • 4. ACL-operator 具体操作符
            • 5. ACL-value 操作对象
          • 5.4.2 多个ACL的组合调用方式
          • 5.4.3 基于域名匹配访问--ACL示例
          • 5.4.4 基于源IP或子网调度访问--ACL示例
          • 5.4.5 基于源地址的访问控制--ACL示例
          • 5.4.6 匹配浏览器类型--ACL示例
          • 5.4.7 基于文件后缀名实现动静分离--ACL示例
          • 5.4.8 匹配访问路径实现动静分离--ACL示例
        • 5.5 自定义Haproxy错误界面
          • 5.5.1 基于自定义的错误页面文件
          • 5.5.2 基于http重定向错误页面
        • 5.6 Haproxy四层负载--数据库示例
        • 5.7 Haproxy https实现
          • 5.7.1 证书制作
          • 5.7.2 https配置示例

4. Haproxy的算法

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

balance参数可以配置在listen或backend选项中。

  • HAProxy的调度算法分为:
    • 静态调度算法
    • 动态调度算法
4.1 静态算法

按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等;

且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。

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

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

1. 示例:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance static-rrserver webserver1 192.168.0.101:80 weight 2 check inter 3s fall 3 rise 5server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
4.1.2 first
  • 根据服务器在列表中的位置,自上而下进行调度
  • 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
  • 其会忽略服务器的权重设置
  • 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
1. 示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance first                 server webserver1 192.168.0.101:80 maxconn 3 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 check inter 3s fall 3 rise 5...上面内容省略...
2. 测试效果:
 #在两台主机上分别执行此循环,可以观察是否102被调度到while true;do curl  172.25.254.100 ; sleep 0.1;done
4.2 动态算法
  • 基于后端服务器状态进行调度适当调整,
  • 新请求将优先调度至当前负载较低的服务器
  • 权重可以在haproxy运行时动态调整无需重启
4.2.1 roundrobin
  • 基于权重的轮询动态调度算法,

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

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

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

  • 支持对real server权重动态调整,

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

1. 示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance roundrobin                 server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
2. 动态调整权重
[root@haproxy ~]# echo "set  weight webserver_80/webserver1 2" | socat stdio  /var/lib/haproxy/haproxy.sock
4.2.2 leastconn
  • leastconn加权的最少连接的动态
  • 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
  • 比较适合长连接的场景使用,比如:MySQL等场景。
1. 示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance leastconnserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
4.3 其他算法

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

4.3.1 source

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。

此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,

但是可以通过hash-type支持的选项更改这个算法

一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,

适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash

1. 示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance sourceserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
2. 测试
[root@node10 ~]# for N in  {1..6}; do curl 172.25.254.100; done
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101
RS1 server - 192.168.0.101

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

4.3.2 map-base 取模法

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

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

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

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

所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3
map-based算法:基于权重取模,hash(source_ip)%所有后端服务器相加的总权重

比如当源hash值时1111,1112,1113,三台服务器a b c的权重均为1,

即abc的调度标签分别会被设定为 0 1 2(1111%3=1,1112%3=2,1113%3=0)

1111 ----- > nodeb

1112 ------> nodec

1113 ------> nodea

如果a下线后,权重数量发生变化

1111%2=1,1112%2=0,1113%2=1

1112和1113被调度到的主机都发生变化,这样会导致会话丢失

1. 取模法配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance sourceserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...#不支持动态调整权重值
[root@haproxy ~]# echo "set weight webserver_80/webserver1 2" | socat stdio /var/lib/haproxy/haproxy.sock
Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.#只能动态上线和下线
[root@haproxy ~]# echo "set weight webserver_80/webserver1 0" | socat stdio /var/lib/haproxy/haproxy.sock[root@haproxy ~]# echo "get  weight webserver_80/webserver1" | socat stdio /var/lib/haproxy/haproxy.sock
0 (initial 1)
4.3.3 一致性hash

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

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

1. 算法
1、后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)
2、客户机哈希环点key1=hash(client_ip)%(2^32) 		得到的值在[0---4294967295]之间,
3、将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
2. hash环偏斜问题
增加虚拟服务器IP数量,比如:一个后端服务器根据权重为1生成1000个虚拟IP,再hash。而后端服务器权
重为2则生成2000的虚拟IP,再bash,最终在hash环上生成3000个节点,从而解决hash环偏斜问题
3. hash对象
  • Hash对象到后端服务器的映射关系:
4. 一致性hash示意图
  • 后端服务器在线与离线的调度方式
5. 一致性hash配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance sourcehash-type consistentserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
4.3.4 uri

基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后

根据最终结果将请求转发到后端指定服务器

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

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

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

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
左半部分:/<path>;<params>
整个uri:/<path>;<params>?<query>#<frag>
1. uri 取模法配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance uriserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
2. uri 一致性hash配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance urihash-type consistentserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
3. 访问测试
  • 访问不同的uri,确认可以将用户同样的请求转发至相同的服务器
root@rs1 ~]# echo RS1  192.168.0.101 index1 > /var/www/html/index1.html
[root@rs1 ~]# echo RS1  192.168.0.101 index2 > /var/www/html/index2.html
[root@rs1 ~]# echo RS1  192.168.0.101 index3 > /var/www/html/index3.html
[root@rs2 ~]# echo RS1  192.168.0.102 index1 > /var/www/html/index1.html
[root@rs2 ~]# echo RS1  192.168.0.102 index2 > /var/www/html/index2.html
[root@rs2 ~]# echo RS1  192.168.0.102 index3 > /var/www/html/index3.html[root@node10 ~]# curl  172.25.254.100/index.html
RS2 server - 192.168.0.102
[root@node10 ~]# curl  172.25.254.100/index1.html
RS1 192.168.0.101 index1
[root@node10 ~]# curl  172.25.254.100/index2.html
RS1 192.168.0.102 index2
[root@node10 ~]# curl  172.25.254.100/index3.html
RS1 192.168.0.101 index3
4.3.5 url_param

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

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

如果无没key,将按roundrobin算法

#假设:
url = http://www.timinglee.com/foo/bar/index.php?key=value#则:
host = "www.timinglee.com"
url_param = "key=value"
1. url_param取模法配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance url_param name,userid 		#支持对多个url_param hashserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
2. url_param一致性hash配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance url_param name,userid 		#支持对多个url_param hashhash-type consistentserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
3. 测试访问
[root@node10 ~]# curl  172.25.254.100/index3.html?userid=111
RS1 192.168.0.101 index3
[root@node10 ~]# curl  172.25.254.100/index3.html?userid=222
RS1 192.168.0.101 index3
[root@node10 ~]# curl  172.25.254.100/index3.html?userid=333
RS1 192.168.0.102 index3
[root@node10 ~]# curl  172.25.254.100/index3.html?userid=444
RS1 192.168.0.101 index3
4.3.6 hdr

针对用户每个http头部(header)请求中的指定信息做hash,

此处由 name 指定的http首部将会被取出并做hash计算,

然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。

1. hdr取模法配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance hdr(User-Agent)server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
2. 一致性hash配置示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...listen webserver_80bind 172.25.254.100:80mode httpbalance hdr(User-Agent)hash-type consistentserver webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5 server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5...上面内容省略...
3. 测试访问
[root@node10 ~]# curl  -v 172.25.254.100
[root@node10 ~]# curl  -vA "firefox" 172.25.254.100
[root@node10 ~]# curl  -vA "sougou" 172.25.254.100
4.4 算法总结
#静态
static-rr--------->tcp/http  
first------------->tcp/http  
#动态
roundrobin-------->tcp/http 
leastconn--------->tcp/http 
random------------>tcp/http#以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http     
hdr--------------->http
4.5 各算法使用场景
first 			#使用较少
static-rr		#做了session共享的web集群
roundrobin
random
leastconn		#数据库
source#基于客户端公网IP的会话保持
Uri--------------->http		#缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http		#可以实现session保持
hdr							#基于客户端请求报文头部做下一步处理
4.6 Haproxy算法大白话解析
4.6.1 first

官方:按服务器声明顺序选择第一个可用服务器
大白话:永远优先用名单里的第一个,除非它超过负载
配置

backend static_poolbalance firstserver rs1 172.25.254.10:80 checkserver rs2 172.25.254.20:80 check

工作逻辑
所有请求都发给 rs1 (172.25.254.10) → 仅当rs1故障时切换至rs2


4.6.2 static-rr

官方:静态加权轮询,运行时不可动态调整权重
大白话:固定权重的轮流值班表
配置

backend weighted_appbalance static-rrserver rs1 172.25.254.10:80 weight 3  # 处理3/4请求server rs2 172.25.254.20:80 weight 1  # 处理1/4请求

工作逻辑
请求序列:rs1 → rs1 → rs1 → rs2 → rs1 → rs1 → rs1 → rs2…


4.6.3 roundrobin

官方:动态加权轮询(默认算法),支持运行时调整权重
大白话:智能版轮流值班,可随时调整工作量
配置

backend dynamic_poolbalance roundrobinserver rs1 172.25.254.10:80 weight 100server rs2 172.25.254.20:80 weight 50

工作逻辑
请求按 2:1 比例分配(100:50)→ rs1处理2次,rs2处理1次,循环往复


4.6.4 random

官方:基于权重随机选择
大白话:摇号分配服务器
配置

backend lotterybalance randomserver rs1 172.25.254.10:80 weight 8server rs2 172.25.254.20:80 weight 2

工作逻辑
每请求独立抽签 → rs1命中率80%,rs2命中率20%


4.6.5 leastconn

官方:优先选择当前连接数最少的服务器
大白话:谁不忙就派活给谁
配置

backend db_poolbalance leastconnserver rs1 172.25.254.10:80server rs2 172.25.254.20:80

工作逻辑

  • 初始状态:请求1 → rs1(连接数0)
  • rs1有10个连接,rs2有5个连接 → 新请求发给rs2

4.6.6 source

官方:基于客户端IP的哈希分派
大白话:相同来源IP永远找同一台服务器
配置

backend sticky_poolbalance sourceserver rs1 172.25.254.10:80server rs2 172.25.254.20:80

工作逻辑
192.168.1.100的哈希值 → 固定分配给rs1
192.168.1.101的哈希值 → 固定分配给rs2


4.6.7 uri

官方:基于完整URI的哈希分派
大白话:相同文件永远从同一服务器获取
配置

backend cache_poolbalance uriserver rs1 172.25.254.10:80server rs2 172.25.254.20:80

工作逻辑
请求 /images/cat.jpg → 哈希值锁定rs1
请求 /videos/demo.mp4 → 哈希值锁定rs2


4.6.8 url_param

官方:基于URL参数的哈希分派
大白话:按指定参数值分配专属服务器
配置

backend api_poolbalance url_param user_idserver rs1 172.25.254.10:80server rs2 172.25.254.20:80

工作逻辑
请求 ?user_id=1001 → 参数哈希后固定分配rs2
请求 ?user_id=2002 → 参数哈希后固定分配rs1


4.6.9 hdr

官方:基于HTTP头部值的哈希分派
大白话:按报文头特征分配专属通道
配置

backend auth_poolbalance hdr(Authorization)server rs1 172.25.254.10:80server rs2 172.25.254.20:80

工作逻辑
头部 Authorization: Bearer xyz → 哈希值锁定rs1
头部 Authorization: Basic abc → 哈希值锁定rs2


4.7 算法选择速查表
需求场景推荐算法示例
简单主备first主服务器优先
固定权重负载static-rr3:1固定流量比
动态权重负载roundrobin自动调整服务器流量
突发流量分散random秒杀请求随机分发
长连接服务leastconnMySQL查询优化
IP会话保持source固定用户访问后端
资源缓存命中uri图片/视频缓存优化
参数化路由url_param按订单号分片处理
头部特征路由hdr按API密钥分配服务器

特殊说明

  • static-rr vs roundrobin:前者权重不可动态调整,后者支持dynamic权重
  • uri 计算整个URI,url_param 只计算指定参数值
  • hdr 需确保指定头部存在,否则回退到roundrobin

5.高级功能及配置

介绍HAProxy高级配置及实用案例

5.1 基于cookie的会话保持

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

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

5.1.1 配置选项
cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]name:		#cookie 的 key名称,用于实现持久连接
insert:		#插入新的cookie,默认不插入cookie
indirect:	#如果客户端已经有cookie,则不会再发送cookie信息
nocache:	#当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,#因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器
5.1.2 配置示例
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfglisten webclusterbind            *:80mode            httpbalance         roundrobinhash-type       consistentcookie  WEBCOOKIE       insert  nocache indirectserver  web1 172.25.254.10:80   cookie  servera check inter 5s fall 3server  web2 172.25.254.20:80   cookie  serverb check inter 5s fall 3[root@Haproxy ~]# systemctl restart haproxy.service
image-20250718163647869 image-20250718163531254
5.1.3 验证cookie信息

1. 通过命令行验证
curl -i 172.25.254.100
curl -i 172.25.254.100curl -b WEBCOOKIE=servera 172.25.254.100
curl -b WEBCOOKIE=serverb 172.25.254.100
image-20250718163833089 image-20250718164002002
5.2 Haproxy状态页–监控实现

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

5.2.1 状态页配置项
stats enable   						# 基于默认的参数启用stats page
stats hide-version   				# 将状态页中haproxy版本隐藏
stats refresh <delay> 				# 设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> 					# 自定义stats page uri,默认值:/haproxy?stats 
stats auth <user>:<passwd>  		# 认证时的账号和密码,可定义多个用户,每行指定一个用户# 默认:no authentication
stats admin { if | unless } <cond> 	# 启用stats page中的管理功能
5.2.2 启用状态页
haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen statsmode            httpbind            172.25.254.100:8888stats           enablestats           refresh         1s      #  自动刷新log             globalstats           uri /status             # 自定义ststs page uristats           auth    du:du           # 认证,此行可以出现多次测试:
浏览器访问:172.25.254.100:8888/status
image-20250718165842619 image-20250718165737685
5.2.3 登录状态页
#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 

image-20250718165757605

5.2.4 backend server信息
1. Session Rate & Sessions
Session Rate 字段含义Sessions 字段含义
cur每秒当前会话数量cur当前会话总量
max每秒新最大会话数量max最大会话量
limit每秒新会话限制量limit限制会话量
Total总共会话量
LBTot选中服务器所用总时间
Last服务器持续连接时间
Wght权重
2. Errors & Warnings
Errors 字段含义Warnings 字段含义
Req错误请求量Retr重新尝试次数
conn错误链接量Redis再次发送次数
Resp错误响应量
3. Bytes & Denied
Bytes 字段含义Denied 字段含义
In网络字节输入总量Req拒绝请求量
Out网络字节输出总量Resp拒绝回复量
4. Server 信息
Server 字段含义
Status后端服务器状态 (UP/DOWN)
LastChk持续检查后端服务器的时间
Act活动链接数量
Bck备份服务器数量
Chk心跳检测时间
Dwn后端服务器 DOWN 数量
Dwntme总 downtime 时间
Thrtle服务器状态
5.3 真实访问主机IP透传

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

5.3.1 七层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 ] 		  如果没有首部才添加首部,如果有使用默认值
1. 未开启透传的七层代理
image-20250718175648447
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaults区:
# option forwardfor       except 127.0.0.0/8			# 此参数注释掉之后,IP透传功能即失效。listen webclusterbind            *:80mode            httpbalance         roundrobinhash-type       consistentserver  web1 172.25.254.10:80  check inter 5s fall 3server  web2 172.25.254.20:80  check inter 5s fall 3[root@Haproxy ~]# systemctl restart haproxy.service# 随后在客户端中进行访问,然后去被访问的RS中进行日志查看(是否能看到)
[root@RS-2 ~]# > /var/log/nginx/access.log			# 清空日志,方便观察curl 172.25.254.100 								# 客户端访问[root@RS-2 ~]# cat /var/log/nginx/access.log		# 查看日志,发现在此日志中是无法看到真实访问源地址的
172.25.254.100 - - [18/Jul/2025:18:05:13 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/8.12.1" "-"
image-20250718180131423 image-20250718180617410
2. 开启透传的七层代理
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
option forwardfor       except 127.0.0.0/8			# defaults中的关键参数# 随后在客户端中进行访问,然后去被访问的RS中进行日志查看(是否能看到)
[root@RS-2 ~]# > /var/log/nginx/access.log			# 清空日志,方便观察curl 172.25.254.100 								# 客户端访问[root@RS-2 ~]# cat /var/log/nginx/access.log		# 查看日志,发现可以查看看源地址的访问
172.25.254.100 - - [18/Jul/2025:18:29:24 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/8.12.1" "172.25.254.1"
image-20250718181725461 image-20250718183044238
5.3.2 四层IP透传

四层对应TCP;七层对应HTTP

此时发现将Haproxy中的关键参数打开了之后发现也是不行,如下图所示。

1. 测试
1.测试
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
option forwardfor       except 127.0.0.0/8listen webclusterbind            *:80mode            tcp			# 四层是tcpbalance         roundrobinhash-type       consistentserver  web1 172.25.254.10:80  check inter 5s fall 3server  web2 172.25.254.20:80  check inter 5s fall 3[root@Haproxy ~]# systemctl restart haproxy.servicecurl 172.25.254.100 								# 客户端访问[root@RS-2 ~]# cat /var/log/nginx/access.log		# 查看日志,发现原先可以透过来的IP没了
172.25.254.100 - - [18/Jul/2025:18:41:02 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/8.12.1" "-"
image-20250718184123329
2. 解决步骤
# Haproxy配置
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
option forwardfor       except 127.0.0.0/8
listen webclusterbind            *:80mode            tcpbalance         roundrobinhash-type       consistentserver  web1  172.25.254.10:80 send-proxy check inter 5s fall 3				# 在IP后添加send-proxy参数server  web2  172.25.254.20:80 send-proxy check inter 5s fall 3				# 在IP后添加send-proxy参数[root@Haproxy ~]# systemctl restart haproxy.service
# 此时要是在客户端访问的话,会出现下图的此种情况!
image-20250718184739581
# Nginx配置
# 在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP# 如果此时只在下方添加一个参数的话,此时可以访问,但是不能将IP透传过来
# 在80后面添加 proxy_protocol 参数
server {listen       80 proxy_protocol;        # 启用此项,将直接无法访问网站,只能通过四层代理的方式进行访问。listen       [::]:80;server_name  _;root         /usr/share/nginx/html;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;error_page 404 /404.html;location = /404.html {}error_page 500 502 503 504 /50x.html;location = /50x.html {}}# 此时发现客户端可以访问,如下图:
curl 172.25.254.100 [root@RS-2 ~]# > /var/log/nginx/access.log# 但是发现IP并未被透传过来
[root@RS-2 ~]# cat /var/log/nginx/access.log
172.25.254.100 - - [18/Jul/2025:19:02:01 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/8.12.1" "-"
image-20250718185830833 image-20250718190101650 image-20250718190242241
# nginx中还是缺少了一个关键的参数
[root@RS-2 ~]# vim /etc/nginx/nginx.conf
# 添加此参数:'"$proxy_protocol_addr"'
http {log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''"$proxy_protocol_addr"'			# 重要!!!!!!!!!!!!!!!!!!!'$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
[root@RS-2 ~]# systemctl restart nginxcurl 172.25.254.100# 此时发现IP被透传过来了!
[root@RS-2 ~]# cat /var/log/nginx/access.log
172.25.254.100 - - [18/Jul/2025:19:07:54 +0800] "GET / HTTP/1.1" "172.25.254.1"200 20 "-" "curl/8.12.1" "-"
image-20250718190939754

image-20250718190846749

3. 四层IP透传–Nginx完整配置详情
image-20250718191358776
4. web服务器日志格式配置

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

#apache 配置(只适于七层,不适用与四层):
LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined#nginx 日志格式:
$proxy_add_x_forwarded_for: 包括客户端IP和中间经过的所有代理的IP
$http_x_forwarded_For:		只有客户端IPlog_format main  '"$proxy_add_x_forwarded_for" - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" $http_x_forwarded_For';
image-20250719160624949
5. 使用Apache将此实验进行完全完成

将RS-1的web配置完成,使其客户端可以访问两台服务主机

# 上面的实验利用Nginx将RS-2完成IP透传之后,并未将RS-1设置好;这里使用Apache将RS-1同样可以利用IP透传技术# 将先前的Nginx的服务关闭
[root@RS-1 ~]# systemctl stop nginx			
[root@RS-1 ~]# systemctl disable --now  nginx# 下载Apache,并开启httpd的服务
[root@RS-1 ~]# yum install -y httpd[root@RS-1 ~]# systemctl enable --now httpd# 将RS-2的nginx页面文件copy一下给RS-1
# 注意:
# 		Nginx  里面的index.html路径为:/usr/share/nginx/html/index.html
# 		Apache 里面的index.html路径为:/var/www/html/index.html
[root@RS-2 ~]# cat /usr/share/nginx/html/index.html
RS-2:172.25.254.20
[root@RS-1 ~]# echo "RS-1:`hostname -I`" > /var/www/html/index.html
[root@RS-1 ~]# cat /var/www/html/index.html
RS-1:172.25.254.10# 在httpd服务配置文件中添加重要参数,后期测试一下(虽然说在四层里面此参数不起作用....)
[root@RS-1 ~]# vim /etc/httpd/conf/httpd.conf
196 <IfModule log_config_module>
197     #
198     # The following directives define some format nicknames for use with
199     # a CustomLog directive (see below).
200     #
201     LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined	# {X-Forwarded-For}i 	重要参数
202     LogFormat "%h %l %u %t \"%r\" %>s %b" common[root@RS-1 ~]# systemctl restart httpd# 将Haproxy中的配置参数原本为nginx提供帮助的send-proxy删去(Apache中不需要此参数)
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webclusterbind            *:80mode            tcpbalance         roundrobinhash-type       consistentserver  web1  172.25.254.10:80 check inter 5s fall 3				# 将此send-proxy参数删去server  web2  172.25.254.20:80 send-proxy check inter 5s fall 3		# 这个是RS-2的不用管[root@Haproxy ~]# systemctl restart haproxy.service			# 修改完配置文件后,将服务重启即可# 在客户端中进行测试,如下图
curl 172.25.254.100
RS-1:172.25.254.10curl 172.25.254.100
RS-2:172.25.254.20# 测试发现:四层的httpd并不能将IP透传过来,七层则可以!
[root@RS-1 ~]# tail -1 /etc/httpd/logs/access_log
- 172.25.254.100 - - [19/Jul/2025:16:27:16 +0800] "GET / HTTP/1.1" 200 20 "-" "curl/8.12.1"
image-20250719161823118
5.4 ACL–访问控制列表

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

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

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

#示例
frontend test_aclbind *:80mode 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#acl test hdr_end(host) -i .org#acl test base_sub -m sub  org#acl test path_sub -m sub  /a#acl test path_end -m sub  /a#acl test path_reg -i ^/tacl test url_sub -m sub leeacl  test path_dir -m sub ause_backend  test_web if testdefault_backend default_webserverbackend default_webservermode httpserver web1 172.25.254.20:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.30:80 check inter 3 fall 3 rise 5
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend test_aclbind    *:80mode    http# 记得在windows中将此文件(C:\Windows\System32\drivers\etc\hosts)添加域名解析
#       acl test hdr_dom(host)  -i      www.ceshi.org
#       acl test hdr_end(host)  .com
#       acl test hdr_beg(host)  bbs.
#       acl test base_sub       -m      sub     org
#       acl test base_sub       -m      sub     du
#       acl test path_sub       -m      sub     ceshiuse_backend             test_web                if      testdefault_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service			# 每次更改配置之后记得要进行服务重启!!!!!
image-20250719203644282 image-20250719203716951
5.4.0 ACL测试参数配置举例
1. acl test hdr_dom(host) www.ceshi.org域名
image-20250719201502899
2. acl test hdr_end(host) .com后缀
image-20250719202724131
3. acl test hdr_beg(host) bbs.前缀
image-20250719203227439
4. acl test base_sub -m sub org
image-20250719205656012
5. acl test base_sub -m sub du
[root@RS-2 ~]# mkdir -p /var/www/html/du[root@RS-2 ~]# echo "172.25.254.20 du--> this is test" > /var/www/html/du/index.html

image-20250719210631397

6. acl test path_sub -m sub ceshi
[root@RS-2 ~]# mkdir -p /var/www/html/ceshi[root@RS-2 ~]# echo "RS-2:172.25.254.20 ceshi" > /var/www/html/ceshi/index.html# 体验5,6的差别
# 6可以做动静分离(访问相同的网址,不同的路径,反馈的内容不相同)

image-20250719211937455

5.4.1 ACL配置选项
#用acl来定义或声明一个acl
acl   <aclname> <criterion>   [flags]     [operator]   [<value>]
acl     名称      匹配规范       匹配模式      具体操作符    操作对象类型
1. 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
2. ACL-criterion 匹配规范
  • 定义ACL匹配规范,即:判断条件
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.timinglee.org
hdr_beg(host) 请求的host开头,如 www.   img.   video.   download.   ftp.
hdr_end(host) 请求的host结尾,如 .com   .net   .cn#示例:
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
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>base     : exact string matchbase_beg : prefix matchbase_dir : subdir matchbase_dom : domain matchbase_end : suffix matchbase_len : length matchbase_reg : regex matchbase_sub : substring matchpath : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>path     : exact string matchpath_beg : prefix match  #请求的URL开头,如/static、/images、/img、/csspath_end : suffix match  #请求的URL中资源的结尾,如 .gif .png .css .js .jpg  .jpegpath_dom : domain matchpath_dir : subdir matchpath_len : length matchpath_reg : regex matchpath_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 timingleeurl : string
#提取请求中的整个URL。url :exact string matchurl_beg : prefix matchurl_dir : subdir matchurl_dom : domain matchurl_end : suffix matchurl_len : length matchurl_reg : regex matchurl_sub : substring matchdst 	 #目标IP
dst_port #目标PORTsrc   	 #源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/24acl invalid_port src_port 0:1023status : integer  #返回在响应报文中的状态码#七层协议
acl valid_method method GET HEAD
http-request deny if ! valid_method
3. ACL-flags 匹配模式
  • ACL匹配模式
-i 不区分大小写
-m 使用指定的正则表达式匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关系
4. 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进行匹配
5. 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.orgexact 		#精确比较substring 	#子串suffix 		#后缀比较prefix 		#前缀比较subdir 		#路径, /wp-includes/js/jquery/jquery.jsdomain 		#域名,www.timinglee.org
- regular expression 	#正则表达式
- hex block 			#16进制
5.4.2 多个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
5.4.3 基于域名匹配访问–ACL示例
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg################ 基于域名 ################
frontend test_aclbind    *:80mode    httpacl     test    hdr_dom(host)   -i      www.yuming.comuse_backend             test_web                if      testdefault_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service# 记得在windows中将此文件(C:\Windows\System32\drivers\etc\hosts)添加域名解析!
# 测试即可

image-20250719221033661

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

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

# 更改配置文件
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
################ 基于源IP或子网调度访问 ################
frontend test_aclbind    *:80mode    httpacl     ctrl_ip         src     172.25.254.20    192.168.0.0/24	 	# 这里表明只有172.25.254.20的IP和192.168.0.0的网段可以访问;其余都不可。use_backend             test_web                if      ctrl_ipdefault_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service# 在RS-1(172.25.254.10)、RS-2(172.25.254.20)与Haproxy(192.168.0.0)中进行测试,如下图:
[root@RS-1 ~]# curl 172.25.254.100
RS-1:172.25.254.10[root@RS-2 ~]# curl 172.25.254.100			# 可以发现仅RS-2可以通过172.25.254.100访问到172.25.254.20
RS-2:172.25.254.20[root@Haproxy ~]# curl 172.25.254.100
RS-1:172.25.254.10
image-20250719222827365
5.4.5 基于源地址的访问控制–ACL示例

拒绝指定IP或者IP范围访问 http-request deny if xxx

# 更改配置文件
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
################ 基于源IP或子网调度访问 ################
frontend test_aclbind    *:80mode    http#       acl     ctrl_ip         src     172.25.254.20    192.168.0.0/24acl     ctrl_ip         src     172.25.254.10						#       use_backend             test_web                if      ctrl_iphttp-request            deny                    if      ctrl_ip	# 使上面提出的172.25.254.10访问服务器时拒绝;其余都可以访问;类似于黑名单。default_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service[root@RS-1 ~]# curl 172.25.254.100
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>[root@RS-2 ~]# curl 172.25.254.100
RS-1:172.25.254.10[root@Haproxy ~]# curl 172.25.254.100
RS-1:172.25.254.10
image-20250719224535030
5.4.6 匹配浏览器类型–ACL示例

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

范例: 拒绝curl和wget的访问

[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
################ 匹配浏览器类型 ################
frontend test_aclbind    *:80mode    httpacl             user_agent_block        hdr_sub(User-Agent)     -i      curl    wget			# curl与wget命令被禁用http-request    deny    if      user_agent_block												# 此处为禁用命令default_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service
image-20250719230618179 image-20250719230847810
5.4.7 基于文件后缀名实现动静分离–ACL示例
1.先做php页面测试文件
# RS-2:Apache中的php测试文件做法
[root@RS-2 ~]# dnf install -y php[root@RS-2 ~]# systemctl restart  httpd[root@RS-2 ~]# vim /var/www/html/index.php
[root@RS-2 ~]# more /var/www/html/index.php
<?phpphpinfo();
?>
# 去浏览器中测试一下172.25.254.20/index.php,测试图片如下:
image-20250719233036963
2.Haproxy配置文件
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
############### 基于文件名后缀名实现动静分离  ################
frontend test_aclbind    *:80mode    httpacl url_staic   path_end  -i  .html  .jpg  .png  .css  .jsacl url_php     path_end  -i  .phpuse_backend             test_web        if      url_phpdefault_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service
# 浏览器中去测试172.25.254.100  172.25.254.100/index.html	172.25.254.100/index.php 如下图:
image-20250719233752601
5.4.8 匹配访问路径实现动静分离–ACL示例
1.RS-1:创建测试目录与文件
[root@RS-2 ~]# mkdir -p /var/www/html/static[root@RS-2 ~]# echo "static-172.25.254.20" > /var/www/html/static/index.html[root@RS-2 ~]# curl 172.25.254.20/static/
static-172.25.254.20
[root@RS-2 ~]# curl 172.25.254.20/static/index.html
static-172.25.254.202.RS-2:创建测试目录与文件
[root@RS-1 ~]# mkdir -p /var/www/html/php[root@RS-1 ~]# cat /var/www/html/index.php
<?phpphpinfo();
?>
[root@RS-1 ~]# cp /var/www/html/index.php /var/www/html/php
2.Haproxy配置文件
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
############### 基于文件名后缀名实现动静分离  ################
frontend test_aclbind    *:80mode    httpacl url_static   path_sub  -m  sub   /static  /php  /images  /javascriptuse_backend             test_web        if      url_staticdefault_backend         default_webserverbackend default_webservermode httpserver web1 172.25.254.10:80 check inter 3 fall 3 rise 5backend test_webmode httpserver web2 172.25.254.20:80 check inter 3 fall 3 rise 5[root@Haproxy ~]# systemctl restart haproxy.service
# 浏览器去搜索172.25.254.100/static
image-20250720000949239
# 示例
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
frontend testaclbind :80mode http###########     ACL settings    #######################acl url_static  path_end -i .jpg .png .css .js .htmlacl url_static  path_end -m sub /static /images /javascriptacl acl_app     path_beg -m sub /api###########     host        ###########################use_backend static_host if url_staticuse_backend api_host if acl_app###########     default server      ###################default_backend default_webserverbackend static_hostmode httpserver web2 192.168.0.101:80 check weight 1 inter 3s fall 3 rise 5backend api_hostmode httpserver web1 192.168.0.102:80 check weight 1 inter 3s fall 3 rise 5backend default_webservermode httpserver web1 172.25.254.10:80 check weight 1 inter 3s fall 3 rise 5#创建相关文件
[root@rs1 ~]# mkdir /usr/share/nginx/html/static
[root@rs1 ~]# echo static 192.168.0.101 > /usr/share/nginx/html/static/index.html
[root@rs2 ~]# mkdir  /var/www/html/api/
[root@rs2 ~]# echo api 192.168.0.102 > /var/www/html/api/index.html#测试访问
[root@node10 ~]# curl 172.25.254.100/api/
api 192.168.0.102
[root@node10 ~]# curl 172.25.254.100/static/
static 192.168.0.101
5.5 自定义Haproxy错误界面

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

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

[root@RS-1 ~]# systemctl stop httpd
[root@RS-2 ~]# systemctl stop httpd#  测试:去浏览器中访问172.25.254.100----> 会发现页面报错很简陋
image-20250720005637200
#haproxy默认使用的错误错误页面
[root@Haproxy ~]# rpm -ql haproxy | grep 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
5.5.1 基于自定义的错误页面文件
# 自定义错误页
errorfile <code> <file> <code> # HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504<file> # 包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀".http",以和一般的html文件相区分# 示例:
errorfile 503 /haproxy/errorpages/503page.http 
# 测试
[root@RS-1 ~]# systemctl stop httpd
[root@RS-2 ~]# systemctl stop httpd[root@haproxy ~]# mkdir /haproxy/errorpages/  -p[root@Haproxy ~]# vim /haproxy/errorpages/503mypage.httpHTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8<html><body><h1>什么动物生气最安静</h1>
大猩猩!!
</body></html>[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaultsmode                    http...内容省略...timeout client          1mtimeout server          1mtimeout http-keep-alive 10stimeout check           10smaxconn                 1000000errorfile 503 /haproxy/errorpages/503mypage.http
[root@Haproxy ~]# systemctl restart haproxy.service# 浏览器访问172.25.254.100进行测试
image-20250720014048957
5.5.2 基于http重定向错误页面
#错误页面重定向
errorloc <code> <url>
#相当于errorloc302 <code> <url>,利用302重定向至指URL#示例:
errorloc 503 https://www.baidu.com
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
defaultsmode                    http...内容省略...timeout client          1mtimeout server          1mtimeout http-keep-alive 10stimeout check           10smaxconn                 1000000errorloc 503 https://www.baidu.com#浏览器访问172.25.254.100 自动跳转到百度

image-20250720014407009

image-20250720014418176
5.6 Haproxy四层负载–数据库示例

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

MySQL
Redis
Memcache
RabbitMQ
# 为两台主机安装mariadb服务
[root@RS-1 ~]# dnf install -y mariadb-server
[root@RS-2 ~]# dnf install -y mariadb-server[root@RS-1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@RS-2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
# 进入配置文件,将添加一项参数:server-id
# 修改如下:
# 			server-id=1
#			server-id=2
image-20250720015433038
[root@RS-1 ~]# systemctl start mariadb.service
[root@RS-1 ~]# mysql
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+[root@RS-2 ~]# systemctl start mariadb.service
[root@RS-2 ~]# mysql
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+
image-20250720020233521
1.Haproxy增添配置
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@Haproxy ~]# systemctl restart haproxy.service			# 推荐这一种
################ 四层负载均衡示例 ############
listen dbserverbind            *:3306mode            tcpbalance         static-rrserver    db1   172.25.254.10:3306      check   inter 2  fall 2  rise 5server    db2   172.25.254.20:3306      check   inter 2  fall 2  rise 5# 或者使用frontend和backend实现
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend mysql_portbind :3306mode tcpuse_backend mysql_rsbackend mysql_rsmode tcpbalance static-rrserver db1 172.25.254.10:3306      check   inter 2  fall 2  rise 5server db2 172.25.254.20:3306      check   inter 2  fall 2  rise 5
2.测试
# RS-1:
[root@RS-1 ~]# mysql -udu -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+[root@RS-1 ~]# mysql -udu -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+# RS-2:
[root@RS-2 ~]# mysql -udu -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           1 |
+-------------+[root@RS-2 ~]# mysql -udu -p -h 172.25.254.100
MariaDB [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           2 |
+-------------+

image-20250720024450303image-20250720024639189

image-20250720024639189

5.7 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端口的请求重向定443bind *:80redirect scheme https if !{ ssl_fc } 
5.7.1 证书制作
[root@Haproxy ~]# mkdir /etc/haproxy/certs/[root@Haproxy ~]# openssl req  -newkey rsa:2048 -nodes  -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt[root@Haproxy ~]# cd /etc/haproxy/certs/[root@Haproxy certs]# cat timinglee.org.key timinglee.org.crt > timinglee.pem
5.7.2 https配置示例
[root@Haproxy ~]# vim /etc/haproxy/haproxy.cfgfrontend  webcluster-80bind            *:80mode            httpbalance         roundrobinredirect        scheme  https   if !{ ssl_fc }          # 全栈加密use_backend     webserverfrontend  webcluster-443bind            *:443   ssl     crt     /etc/haproxy/certs/timinglee.pemmode            httpbalance         roundrobinuse_backend     webserverbackend  webserverserver web1 172.25.254.10:80 check  inter 3 fall 3 rise 2server web2 172.25.254.20:80 check  inter 3 fall 3 rise 2[root@Haproxy ~]# systemctl restart haproxy.service
[root@Client ~]# curl -IkL http://172.25.254.100
HTTP/1.1 302 Found
content-length: 0
location: https://172.25.254.100/
cache-control: no-cacheHTTP/1.1 200 OK
date: Sun, 20 Jul 2025 08:25:21 GMT
server: Apache/2.4.57 (Red Hat Enterprise Linux)
last-modified: Sat, 19 Jul 2025 08:02:27 GMT
etag: "14-63a43a9da2ccf"
accept-ranges: bytes
content-length: 20
content-type: text/html; charset=UTF-8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89854.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89854.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89854.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git fork的项目远端标准协作流程 仓库设置[设置成upstream]

这是一个在开源协作中非常常见的配置。 简单来说&#xff0c;upstream 在这里指的是你 Fork 来的那个原始的、官方的仓库。 下面我们来详细解释一下这个 git remote -v 输出的含义&#xff1a; 1. 两条“遥控器” (Remotes) 你的 git 配置了两个远程仓库的地址&#xff0c;就像…

[FFmpeg] 输入输出访问 | 管道系统 | AVIOContext 与 URLProtocol | 门面模式

链接&#xff1a;https://trac.ffmpeg.org/ docs&#xff1a;FFmpeg FFmpeg 是一个强大的多媒体框架&#xff0c;旨在处理媒体处理的各个阶段。 它就像一个数字媒体工厂&#xff0c;包含以下部门&#xff1a;打包/解包&#xff08;容器处理&#xff09;、 转译/压缩&#xff…

微服务的编程测评系统2

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言工程创建创建ck-oj创建oj-modules创建具体微服务oj-system推送码云管理员登录逻辑分析docker安装mysqldocker客户端docker desktop安装安装mysqlmysql-plus和数据…

AR智能巡检:电力运维的数字化变革

在电力行业快速发展的当下&#xff0c;传统运维方式已难以满足现代电网对高效、安全的需求。近年来&#xff0c;增强现实&#xff08;AR www.teamhelper.cn &#xff09;技术的兴起为电力巡检带来了全新的解决方案。通过实时数据可视化、远程协作和智能分析&#xff0c;AR技术…

NeRF和3DGS原理详细

NeRF和3DGS一、传统三维表征方法1.1 显示表征1.2 隐式表征二、NeRF&#xff08;Nerual Radiance Field&#xff09;2.1 NeRF场景表示2.2 NeRF训练流程2.3 NeRF体渲染2.4 NeRF位置编码2.5 NeRF体素分层采样&#xff08;Volume Hierarchical Sampling&#xff09;2.6 NeRF网络结构…

035_ClaudeCode_MCP_介绍

035_ClaudeCode_MCP_介绍 摘要 Model Context Protocol&#xff08;MCP&#xff09;是一个开放的标准化协议&#xff0c;专为大型语言模型提供上下文数据而设计。作为Claude Code生态系统的重要组成部分&#xff0c;MCP如同"AI应用程序的USB-C端口"&#xff0c;提供…

Python 程序无法找到 Oracle 的 64 位客户端库 (libclntsh.so)

数据库错误: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://oracle.github.io/odpi/doc/installation.html#linux for help 这个错误表明 Python 程序无法找到…

Kubernetes常用命令总结

文章目录Kubernetes常用命令总结1. 集群管理命令kubectl cluster-infokubectl get nodeskubectl describe node <node-name>kubectl top nodes2. Pod相关命令kubectl get podskubectl get pods -o widekubectl describe pod <pod-name>kubectl logs <pod-name&g…

roboflow使用教程

如何利用roboflow标注自己的训练集、调用开源数据集 官网&#xff1a;Roboflow: Computer vision tools for developers and enterprises&#xff08;国内代理进不去&#xff09; 先注册登陆进去 训练自己的数据集 点击“New Project”,名字按照自己的需求来 我不想写了&am…

IDEA中使用Tomcat两种方式

Catalogue1 集成本地Tomcat2 Tomcat Maven插件&#xff08;推荐&#xff09;1 集成本地Tomcat 将本地Tomcat集成到Idea中&#xff0c;然后进行项目部署即可 点击编辑配置 点击加号 添加local的Tomcat 配置Application Server 可以修改一下Name 至此&#xff0c;配置完成 …

服务器上的文件复制到本地 Windows 系统

在 Windows 上通过 SSH 连接到 Linux 服务器后&#xff0c;如果需要将服务器上的文件复制到本地 Windows 系统&#xff0c;可以使用以下几种方法&#xff1a;方法 1&#xff1a;使用 scp&#xff08;Secure Copy&#xff09;命令 scp&#xff08;基于 SSH 的安全复制&#xff0…

大语言模型置信度增强实战指南

LLM怎么简单增强置信度 在大语言模型(LLM)的应用中,“置信度增强”核心目标是提升模型输出的可靠性(减少错误/幻觉) 并让模型更清晰地表达自身的不确定性(避免“一本正经地胡说”)。常用方式可分为“输出优化”“知识补充”“校准调整”三大类, 一、基于“推理过程优…

NLP:人名分类器案例分享

本文目录&#xff1a;一、案例介绍&#xff08;一&#xff09;关于人名分类&#xff08;二&#xff09;人名分类数据预览二、案例步骤&#xff08;一&#xff09;导入工具包&#xff08;二&#xff09;数据预处理1. 获取常用的字符数量2. 国家名种类数和个数3.读数据到内存4.构…

3分钟实战!用DeepSeek+墨刀AI生成智能对话APP原型图

如今&#xff0c;AI生成原型图已经逐渐成为产品经理的一项常用辅助技能&#xff0c;不仅能加快设计进程&#xff0c;还能显著提升前期沟通效率。最近我尝试将大语言模型工具与AI原型工具结合测试&#xff0c;目标是看看是否能生成更高质量的原型页面。直到我使用DeepSeek墨刀AI…

CentOS网络配置与LAMP环境搭建指南

一、CentOS配置网络1、查看网卡名称ifconfig2、找到网卡对应配置文件网卡存放路径 &#xff1a;/etc/sysconfig/network-scriptscd /etc/sysconfig/network-scripts3、修改网卡对应配置文件使用 vi/vim 打开文件&#xff0c;查看以下内容vim ifcfg-ens33将ONBOOTno 改为 ONBOOT…

TinyMCE 富文本编辑器在 vue2 中的使用 @tinymce/tinymce-vue

TinyMCE是一款功能强大、高度可定制的富文本编辑器。官方文档 TinyMCE DOCS tinymce-vue包的版本4及更高版本支持Vue.js 3。但不支持Vue.js 2.x。对于Vue.js 2。X应用程序&#xff0c;使用tinymce-vue版本3。 安装TinyMCE和Vue集成包 npm install tinymce/tinymce-vue3 tiny…

LP-MSPM0G3507学习--04GPIO控制

关键函数&#xff1a; DL_GPIO_readPins(GPIO_Regs* gpio, uint32_t pins):同时读一组端口DL_GPIO_writePins(GPIO_Regs* gpio, uint32_t pins)&#xff1a;同时写一组端口DL_GPIO_setPins(GPIO_Regs* gpio, uint32_t pins)&#xff1a;对指定某组端口的某管脚置高DL_GPIO_cle…

LVS(Linux virtual server)-实现四层负载均衡

一、简介LVS:Linux Virtual Server&#xff0c;负载调度器&#xff0c;内核集成&#xff0c;章文嵩&#xff0c;阿里的四层SLB(Server LoadBalance)是基 于LVSkeepalived实现LVS 官网: http://www.linuxvirtualserver.org/二、LVS运行原理2.1LVS 的集群结构2.2lvs相关概念RS&am…

Kubernetes CNI网络插件性能瓶颈排查与优化实践

Kubernetes CNI网络插件性能瓶颈排查与优化实践 CNI&#xff08;Container Network Interface&#xff09;是 Kubernetes 网络层的核心组件&#xff0c;不同 CNI 插件实现了容器间网络通信、多租户隔离、流量限速等功能。然而在大规模集群或高并发业务场景下&#xff0c;CNI 插…

20250720-6-Kubernetes 调度-nodeName字段,DaemonS_笔记

一、污点与容忍&#xfeff;1. 给节点添加污点&#xfeff;1&#xff09;命令格式基本语法&#xff1a;kubectl taint node [node] keyvalue:[effect]示例&#xff1a;kubectl taint node k8s-node1 gpuyes:NoSchedule操作说明&#xff1a;与打标签命令类似&#xff0c;将"…