七层负载均衡集群HAProxy使用及原理

一、为什么使用haproxy

后端检测将挂了的主机访问打到正常的主机上,就是我们所说的负载均衡,保证业务的高可用性,方便业务后期的水平动态扩展

二、七层负载和四层负载及正反向代理的含义

1、四层负载

(1)通过IP+PORT决定负载均衡的去向

(2)对流量请求进行NAT处理,转发至后台服务器。

(3)记录tcp、udp流量分别是由哪台服务器处理

(4)支持四层代理的软件

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

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

Haproxy:模拟四层妆发

2、七层负载

(1)通过虚拟URL或主机IP进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。

(2)代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务tcp连接

(3)支持七层代理的软件

Nginx:基于http协议,通过proxy_pass

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

3、四层和七层的区别

        四层的负载均衡是通过发布三层的IP地址+端口号来识别流量需不需要做负载均衡,并且需要对处理的流量进行NAT处理,转发至后台服务器并记录下这个TCP或者UDP的流量由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。

        七层的负载均衡是在四层的基础上,例如一个Web服务器的负载均衡,除了根据VIP+端口辨别还可以可以根据URL、浏览器类别、语言来识别流量是否需要负载均衡

(1)分层位置:四层负载均衡实在传输层及以下,七层负载均衡在应用层及以下

(2)性能:四层负载均衡不能解析报文消息内容,在网络吞吐量和处理能力上较高,七层能解析应用层报文消息,识别URL、Cookie、HTTPheader等信息。

(3)功能类别:四层负载均衡类似于路由器;七层类似于代理服务器

(4)原理:四层负载均衡是基于ip+prot;七层是基于url或主机ip

(5)安全性:四层负载均衡无法识别DDos攻击;七层可防御SYN Cookie/Flood攻击

4、正反向代理

(1)正向代理:是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。例如你想要租房子,可以通过中介来寻求一些房源,这个中介就是所谓的正向代理。

0e07cbc6a24a41b38967455b813f4a70.png

(2)反向代理:指服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。例如你作为客户想去租房找一个房东,结果对面是一个二房东,就是真实房东找的代理房东,这个代理房东就是反向代理。

fc316ac3c2f544849fedf1de419fc2c9.png

三、HAProxy简介

HAProxy是法国开发者Willy Tarreau在2000年使用C语言开发的一个开源软件

是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器

支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计

四、实验环境准备

1、三台rhel9.1的虚拟机

2、IP

Haproxy:172.25.254.100

Webserver1:172.25.254.10

Webserver2:172.25.254.20

3、提前关闭防火墙和selinux

4、为了后续体现不同web的配置不同,我们在两台Webserver上分别安装nginx和apache

(1)webserver1:

[root@Webserver ~]# dnf install nginx -y

[root@Webserver ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html

[root@Webserver ~]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

(2)webserver2:

[root@Webserver ~]# dnf install nginx -y
[root@Webserver ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index.html
[root@Webserver ~]# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

五、HAProxy的基本部署方法及负载均衡的实现

1、软件的安装

HAProxy:

[root@HAProxy ~]# dnf install haproxy -y

[root@HAProxy ~]# systemctl enable --now haproxy
Created symlink /etc/systemd/system/multi-user.target.wants/haproxy.service → /usr/lib/systemd/system/haproxy.service.

———将vim格式设置成haproxy配置文件需要的格式

[root@HAProxy ~]# cat ~/.vimrc
set ts=4 ai sw=4

2、基本配置信息

2.1全局配置段global

进程及安全配置相关的参数

性能调整相关参数

Debug参数

2.2代理配置段proxies

defaults:为frontend、backend、listen提供默认配置

frontend:前端,相当于nginx中的server{}

backend:后端,相当于nginx中的upstream{}

listen:同时拥有前端和后端配置,配置简单,生产推荐使用

2.3global配置

2.3.1配置参数

参数作用
chroot锁定运行目录
deamon以守护进程运行
user, group, uid, gid运行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
pidfile指定pid文件路径
log 127.0.0.1 local2 info定义全局的syslog服务器;日志服务器需要开启UDP协议, 最多可以定义两个

2.3.2配置文件global的介绍

35dd9def61a1470b97b35cb76b25db05.png

2.3.3示例

2.3.3.1nbproc参数开启多进程

开启前

2f5292124c064a9aa1e2284415d3d39b.png

编辑配置文件

d2e1a3665360462abca66addf4c6b27e.png

开启后的进程

76f46a21e37543bfa4896d43f24b2d8b.png

注意:开启进程不是越多越好,看你的cpu核心数量,你的cpu有几核才能开几个

固定进程的cpu内核使用,避免cpu使用的飘逸

15d9fd19383146f2a2c5acbc9029c7b8.png

2.3.3.2nbthread参数开启多线程

开启前

5b790d5d8aac43c792e9ca6c4dd47959.png

编辑配置文件

d35d068a6c5140fa9a2d32a41752fe17.png

开启后

40e52617b2c54401b59fc25e62b18d8b.png

2.3.3.3自定义日志

编辑rsyslog配置文件

[root@HAProxy ~]# vim /etc/rsyslog.conf

f5d53e82e6d44f7e853da0718d7cd655.png

69982c2f72394c079b58a4c09eaf88e0.png

重启服务

先启动rsyslog再启动haproxy,就可以看到自定义的日志文件已经生成了

c8abdd09347d47d1b06a7768b3f4a4bf.png

注意:global中的参数在defaults中也能写,但是匹配下来后两个配置段中都有的参数defaults会覆盖掉global中的参数

2.4proxies配置

2.4.1proxies-defaults

mode        http        #HAProxy实例使用的连接协议

log        global        #指定日志地址和记录日志条目的

syslog/rsyslog日志设备

                                #此处global表示使用global配置段中设定的log值

option        httplog        #日志记录选项,httplog表示记录与http会话相关的各种数学

                                  #包括http请求、会话状态、连接数、源地址及连接时间等

option        dontlognull        #表示不吉利空会话连接日志

option        http-server-close        #等待客户端完整HTTP请求的时间

option        forwardfor        except 127.0.0.0/8        #透传客户端真实IP至后端web服务器

option        redispatch        #当server id 对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发

option        http-keep-alive        #开启与客户端的会话保持

retries        3        #连接后端服务器失败次数

timeout        http-request        1000s        #等待客户端请求完全被接收和处理的最 长时间

timeout        queue        60s        #设置删除连接和客户端收到503或服务不可 用等提示信息前的等待时间

timeout        connect        120s         #设置等待服务器连接成功的时间

timeout        client        600s         #设置允许客户端处于非活动状态,即既不发 送数据也不接收数据的时间

timeout        server        600s         #设置服务器超时时间,即允许服务器处于既 不接收也不发送数据的非活动时间

timeout        http-keep-alive        60s         #session 会话保持超时时间,此时间段内 会转发到相同的后端服务器

timeout        check        10s         #指定后端服务器健康检查的超时时间

maxconn         3000        #可承受的最大并发连接量

default-server inter 1000 weight 3        #对后端检测的默认参数,inter每隔多长时间,weight访问多少次

介绍配置文件

290b14d9eb254b039163cfa7e89d7b08.png

2.4.2proxies-frontend

frontend配置参数:

bind:指定监听地址,IPV4或IPV6,可以监听多个IP或端口

#格式:

bind [<address>]:<prot_range>[,...]

——注意,如果需要绑定在非本机的IP,需要开启内核参数:net.ipv4.ip_nonlocal_bind=1

2.4.3proxies-backend

定义一组后端服务器,backend服务器将被frontend进行调用。

backend的名称必须唯一,并且必须在listen或frontend中事先定义才可以使用,否则服务无法 启动

mode        http|tcp

option        server        #指定负载协议类型,和对应的frontend必须一致 #配置选项 #定义后端real server,必须指定IP和端口

 代码示例:

d3c4ab95eebf4b928408e38365a20a4d.png

测试效果:

372291951c7d45a984a77ab8527ede9c.png

2.4.3.1server配置

#针对一个server配置

check        #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没 有其它配置也可以启用检查功能

                #默认对相应的后端服务器IP和端口,利用TCP连接进行周期性健康性检查,注意必须指定 端口才能实现健康性检查

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

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

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

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

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

weight         <weight>         #默认为1,最大值为256,0(状态为蓝色)表示不参与负载均衡,但仍接受持久连接

backup        #将后端服务器标记为备份状态,只在所有非备份主机down机时提供服务,类似SorryServer

disabled       #将后端服务器标记为不可用状态,即维护状态,除了持久模式

                        #将不再接受连接,状态为深黄色,优雅下线,不再接受新用户的请求

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

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

示例:

(1)check

7d55b47c50594ddcabe3720dafcc3013.png

(2)用backup参数实现sorryserver的设置

配置一个做sorryserver的主机,这里不想开另外一台客户端所以使用了HAproxy的主机做,所以需要改端口号为8080

首先安装http

[root@HAProxy ~]# dnf install httpd -y
[root@HAProxy ~]# vim /etc/httpd/conf/httpd.conf
a30c7bdba9734bb6b218a672e1f8ce51.png

f23f73ee85dd42f4bfa054719ce59682.png

为了实现我们的sorryserver,先关掉两台后台服务器的nginx

[root@webserver1 ~]# systemctl stop nginx
[root@webserver2 ~]# systemctl stop nginx

可以测试一下访问我们的Haproxy

e4585cb9fe9b4e97aecdf8a4bdaa56b8.png

为了我们设置的sorryserver生效我们还需要配置haproxy的配置文件

9f2f3401094f428cb815f1efed96ae66.png

测试效果:

重启后就会跳出我们之前设置的日志信息

1cd0342834974b3785ebe99943dad308.png

fec352acfe3e4beea975997bfabb7da4.png

那如果我们有时需要维护一台后端服务器,就用disabled指定服务器下线

先将两台nginx开启

[root@webserver1 ~]# systemctl start nginx
[root@webserver2 ~]# systemctl start nginx

编辑配置文件

dd7b0bcdeaad45e993db13b5005cf721.png

测试效果:

就不会访问到10主机上了

d5e3d25fbded4118b0a5612076ae8de8.png

设置请求重定向

编辑配置文件

907ac7b3bffc467dbeca9d73326db7f8.png

测试效果:

48b11d8f23684024b80ea88686a71a97.png

maxconn设置最大并发连接

f1ee82018a1c4350a77c23c4dbedfa66.png

测试效果:

1260e49626c0408ab6f2dcb352ad8460.png

可以看到,当两台服务器一起访问的时候另一台后端服务器就已经访问不到了

4f628035f2e740d9adf32d580c37c5f1.png

我们关掉一台的死循环访问才会逐渐有出现10 20轮询访问的情况

053f6f8854a445bbb25c9d322e54a5fd.png

2.4.4proxies-listen简化配置

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

listen配置示例:

b9fa71a442f246b1bd089115af4267d7.png

示例效果:

2865a30360f240cfaab0af5aaf226a36.png

六、HAProxy热更新方法

1、socat工具

因为我们的配置文件中不止一个集群,如果像以上那种改法,每次改一个集群都要重启一遍服务器,也就会刷新配置文件中全部的集群,可能会导致影响其他集群,所以我们用socat工具来一条一条的更改我们需要改的集群而不影响其他集群。

2、socat使用方法

需要HAProxy主机配置文件中有一条来记录状态的文件,通过给这个文件提权来方便控制HAProxy中的配置

d8dedf9e41c148e39348777a88ff618b.png

重启服务

c53dc103a8f24c28bdd37ccb8ec6a120.png

在HAProxy主机中安装socat工具

[root@HAProxy ~]# dnf install socat -y

查看帮助文档

socat -h
echo "help" | socat stdio /var/lib/haproxy/stats

914ead5401584994af54a0736bb27617.png

常用示例:

(1)查看haproxy状态

2c24c2d3b97b46438e4bee4c0e3d5d6d.png

(2)查看后端主机(集群)状态

[root@HAProxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats

e63ff348007e40e4973e5cdefef21ec0.png

(3)查看并设置集群权重

查看两台主机的权重

[root@HAProxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats  1 (initial 1)

[root@HAProxy ~]# echo "get weight webcluster/web2" | socat stdio /var/lib/haproxy/stats
1 (initial 1)

——将主机2的权重改为2

[root@HAProxy ~]# echo "set weight webcluster/web2 2" | socat stdio /var/lib/haproxy/stats
[root@HAProxy ~]# echo "get weight webcluster/web2" | socat stdio /var/lib/haproxy/stats  2 (initial 1)

测试看是生效的:

47a70af710e44f1c8105392aa207ad98.png

(4)设置下线后端服务器

设置下线两台服务器

[root@HAProxy ~]# echo "disable server webcluster/web1" | socat stdio /var/lib/haproxy/stats

[root@HAProxy ~]# echo "disable server webcluster/web2" | socat stdio /var/lib/haproxy/stats

测试效果出现sorryserver表示成功下线两台服务器:

437972c561e14c6ca27133d3e5df4bc8.png

开启后端服务器

[root@HAProxy ~]# echo "enable server webcluster/web2" | socat stdio /var/lib/haproxy/stats

[root@HAProxy ~]# echo "enable server webcluster/web1" | socat stdio /var/lib/haproxy/stats

访问一下:

5db302babacd4b8793e96fd0e501c8be.png

(5)针对多进程处理方法

首先更改配置文件

4aec30c8ea2b4795a1f2e79eed77752b.png

[root@HAProxy ~]# systemctl restart haproxy
[root@HAProxy ~]# ll /var/lib/haproxy/
total 0
srw------- 1 root root 0 Aug 11 12:12 stats
srw------- 1 root root 0 Aug 11 12:55 stats1
srw------- 1 root root 0 Aug 11 12:55 stats2

——可以看到之前的状态文件不能使用了

[root@HAProxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats                   2024/08/11 12:56:56 socat[34419] E connect(5, AF=1 "/var/lib/haproxy/stats", 24): Connection refused

进程1
[root@HAProxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats1
Name: HAProxy
Version: 2.4.17-9f97155
Release_date: 2022/05/13
Nbthread: 1
Nbproc: 2
Process_num: 1
Pid: 34415
 

进程2
[root@HAProxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats2
Name: HAProxy
Version: 2.4.17-9f97155
Release_date: 2022/05/13
Nbthread: 1
Nbproc: 2
Process_num: 2
Pid: 34416

七、HAProxy中的算法

1、静态算法

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

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

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

后端主机数量没有限制

编辑配置文件

30a115de5adb4694ab8265422c54bfe0.png

不支持热处理测试:

[root@HAProxy ~]# echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/statsBackend is using a static LB algorithm and only accepts weights '0%' and '100%'.

1.2first

自上而下的进行调度,只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务器,会忽略服务器的权重设置

不支持热处理

a54618638a954e3c9fb4c7d55d04aa71.png

测试效果:

在多台主机上死循环访问看效果

c3b97ed881a54071bc1a4e08728bb08c.png

2、动态算法

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

2.1roundrobin 谁闲给谁

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

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

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

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

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

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

编辑配置文件

cbdf10a5aed044e58ea9b2aa2f7d99c4.png

支持热处理测试:

[root@HAProxy ~]# echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/stats

[root@HAProxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats  1 (initial 2)

2.2leastconn谁链接最少给谁

leastconn加权的最少连接的动态

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

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

编辑配置文件

75d5a1fa18514309a58c2ad95d9ccfd1.png

支持热处理

[root@HAProxy ~]# systemctl restart haproxy
[root@HAProxy ~]# echo "set weight webcluster/web1 2" | socat stdio /var/lib/haproxy/stats
[root@HAProxy ~]# echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/stats
[root@HAProxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats  1 (initial 2)

非权重优先调度

dcaa1e12d41947cbba4764cc8bd4b54d.png

3、其他算法

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

源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一 个后端web服务器。默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP 模式下使用。适用于session会话保持但不支持 cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法 和一致性hash。

3.1source

编辑配置文件

11e5dc3c34b046d881c6b5f29d06a310.png

配置后的效果:

01120f9195914133b92f5f07ef9acd85.png

相同hash值的流量被定向到同一台服务器

3.1.1map-base取模法

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

此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度 缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果 整体改变

所谓取模算法,就是计算两个数相除之后的余数

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

比如当源hash值是1111,1112,1113,三台服务器abc的权重均为1,即abc的调度标签分别会被设定为0 1 2(1111%3=1,1112%3=2,1113%3=0)

1111---->b

1112---->c

1113---->a

如果a下线后,权重数量发生变化(1111%2=1,1112%0,1113%2=1)

1112和1113都被调度到的主机发生变化,这样会导致原本没有挂掉的服务器与客户机的会话丢失

示例:34608673725e4ca89e2e8f651c5ef06f.png

67bb22c00ebf46aebfe8b1943c0fbfcd.png

3.1.2一致性hash

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

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

595afadd52d84b02a6f17752bde50ad5.png

示例:

461f0a7b2d014da28f4bbd653041597f.png

a09d7bf4559642bba4464fc282d3514c.png

3.2uri

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

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

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

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

一致性hash配置:

编辑配置文件

741fbb505330439ca3edcc0dd816490d.png

设置不同的uri

[root@webserver1 ~]# echo web1index1 - 172.25.254.10 >

/usr/share/nginx/html/index.html
[root@webserver1 ~]# echo web1index1 - 172.25.254.10 > /usr/share/nginx/html/index1.html
[root@webserver1 ~]# echo web1index2 - 172.25.254.10 > /usr/share/nginx/html/index2.html
[root@webserver1 ~]# echo web1index3 - 172.25.254.10 > /usr/share/nginx/html/index3.html
[root@webserver2 ~]#  echo web1index1 - 172.25.254.20 > /usr/share/nginx/html/index1.html
[root@webserver2 ~]#  echo web1index2 - 172.25.254.20 > /usr/share/nginx/html/index2.html
[root@webserver2 ~]#  echo web1index3 - 172.25.254.20 > /usr/share/nginx/html/index3.html

测试效果:

只要uri不变,最后访问的主机不变

5a3cb9f8fc0641c0b48b329777cc2ba3.png

3.3url_param

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

一致性hash配置示例:

5c04ef11ffe74ec49490ec47975f3fd1.png

测试效果:

659648bd55ab4004aea7eba9b6e34202.png

3.4hdr(User-Agent)

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

一致性hash配置示例:

7f9b1e6e4b49438aac64a52e20991297.png

测试效果:

bfaeeaad62fe4c1b911addb614c6c61d.png

3.5算法总结

静态        不支持热处理和慢启动

static-rr------>tcp/http        不管服务器的状态直接轮询

first----------->tcp/http        先访问满一个再访问另一个

动态        支持热处理和慢启动

roundrobin------>tcp/http        谁负载小权重高就访问谁

leastconn--------->tcp/http        谁链接少权重高就访问谁

以下静态和动态取决于hash_type是否consistent

source------------>tcp/http        源地址hash,用hash环保持hash一致性

Uri--------------->http        基于访问地址的内容进行hash

url_param--------->http        基于访问发送的请求进行hash

hdr--------------->http        基于(http报文头)不同的浏览器进行hash

八、高级功能及配置

1、Haproxy的状态页

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

通过配置子配置文件设定状态页

ad6299ccecaa495e81e6f293cf2bdcd2.png

[root@HAProxy ~]# cd /etc/haproxy/conf.d
[root@HAProxy conf.d]# ls
[root@HAProxy conf.d]# vim webcluster.cfg

2f628d05df6b4cd1aeea91a3122beba8.png

测试:

d0d472a30e254ee28994d8716fe63cca.png

08454ceac77740a38613424d2e3b8f9a.png

关掉一个后端服务器

a51a7661dfac476795245136068565f1.png

2、基于cookie的会话保持

当浏览器发送给haproxy时都带一个cookie值,使调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前已经被session共享服务器代替,session使保存在服务器上。

注意:不支持tcp 支持http

配置示例:

e1a7c050c12c4a51b7646f7872bc2bdc.png

890a7b35f20848daa3e9faefeba921c1.png

测试效果:

18eddaa0f55c431386b215dfd3d60467.png

通过命令验证

d5eb9c954f1a4751913b8445b1759e28.png

3、IP透传

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

3.1七层IP透传

看没有IP透传参数的效果:

2c568614524f4b1f807821ffbb98f36d.png

f31126393dc347639a3605ce621eca73.png

将参数注释去掉后:

33578a56678d427dacd4edfcda3d65c5.png

如果后端服务器使用apache需要对其配置文件设定

[root@webserver1 ~]# vim /etc/httpd/conf/httpd.conf

0454532bad604f2f8ffd9fb3fd0170f7.png

3fd385b8511d45d89e244aef0ae59e32.png

3.2四层IP透传

编辑配置文件设置tcp

056f910fceb04212bd8edfe2f5508ac9.png

编辑nginx配置文件:

2635fbe6bb934719a3d6efb09831fb25.png

6170546321e44b6c8744e662bf518a4b.png

编辑haproxy配置文件:

只用给nginx服务器添加代理参数

d4b5b026daab497788dfafc644560d0a.png

因为apache现在不支持四层透传了,所以将10服务器的apache关闭,开启nginx,同时haproxy中代理加上

查看日志文件:

[root@webserver1 ~]# tail -n 3 /var/log/nginx/access.log
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"
[root@webserver2 ~]# tail -n 3 /var/log/nginx/access.log
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"
172.25.254.100 - - [11/Aug/2024:17:42:31 +0800] "GET / HTTP/1.1" 200 27 "-" "curl/8.4.0" "-" "172.25.254.1"

4、ACL

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

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

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

4.1ACL配置选项

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

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

4.1.1ACL-Name名称

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

4.1.2ACL-criterion 匹配规范

(1)hdr:提取在一个HTTP请求报文的首部, <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也会匹 配

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

<scheme>://<user>:<passwd>@#<host>:<port>/<path>;<params>#?<query>#<frag>

base_begprefix match
base_dirsubdir match
base_domdomain match
base_endsuffix match
base_lenlength match
base_regregex match
base_subsubstring match

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

path_beg请求的URL开头,如/static、/images、/img、/css
path_end请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
path_domdomain match
path_dirsubdir match
path_lenlength match
path_regregex match
path_subsubstring match

(4)url:提取请求中的整个URL。

url_begprefix match
url_dirsubdir match
url_domdomain match
url_endsuffix match
url_lenlength match
url_regregex match
url_subsubstring match

4.1.3ACL-flags匹配模式

-i 不区分大小写

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

-n 不做DNS解析

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

4.1.4ACL-operator 具体操作符

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进行 匹配

4.1.5ACL-value 操作对象

Boolean布尔值
integer or integer range整数或整数范围,比如用于匹配端口范围
IP address / networkIP地址或IP范围, 192.168.0.1 ,192.168.0.1/24
exact精确比较
substring子串
suffix后缀比较
prefix前缀比较
subdir路径, /wp-includes/js/jquery/jquery.js
domain域名,www.timinglee.org
regular expression正则表达式
hex block16进制

4.2 多个ACL的组合调用方式

逻辑处理

与:隐式(默认)使用

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

否定:使用 "!" 表示

4.3ACL示例-域名匹配

编辑子配置文件

[root@HAProxy conf.d]# vim ACL.cfg
[root@HAProxy conf.d]# systemctl restart haproxy
[root@HAProxy conf.d]# pwd
/etc/haproxy/conf.d

b4a1d42025e24f4688439a738fa1c659.png

给windows的host文件添加域名

如果没有权限需要在下面这个目录点击文件

5e47a858b6d440afa21170d84934802c.png

15e8877c5c574f6b8bd3e1fc116e4da5.png

dad4b67bd6e34cdda25471168a58a8c3.png

测试结果:

405c9785df734dbc92c5ceeb6892b44f.png

编辑子配置文件

4c5c7fdb888a4ccc92eb163a317c362d.png

再添加域名

a5691165363844f6a2fe1ca959f7011f.png

测试结果:

中间没访问到是因为服务器还没反应过来

1209ec93be134d169a79b76555a1f14f.png

4.4ACL示例-基于子串访问

8d381a965a634380bfbf7067eb5fd0e1.png

测试:

f4fbc10bf82f44de884ac03d218e822d.png

ba5bdbeb86084aa9b4320d69b7af7f0b.png

[root@webserver1 ~]# mkdir /var/www/html/jcl -p
[root@webserver1 ~]# echo 172.25.254.10 jcl > /var/www/html/jcl/index.html

1a2421ca34e644da804011b19970b7db.png

b72bada896ce42bf908179a06b1d2103.png

测试:

230c91fd942442f1971a77658033edc6.png

4.5ACL示例-基于path匹配(/后的内容)

dcfcc4dd77e946d39739997ec577e86f.png

测试:

ddb2f6c7704d46d9af22174e5685f352.png

4.6ACL示例-逻辑处理

8e939b279d6e4c3bbe5c8a17401bc6f0.png

[root@webserver2 ~]# mkdir -p /usr/share/nginx/html/jcl
[root@webserver2 ~]# echo 172.25.254.20 jcl > /usr/share/nginx/html/jcl/index.html

测试:

ec6b12f6eb4844e3adf7cdabdf40f84e.png

34a955fbcf0246a2b7caafac8335f1de.png

测试:

b864330798e348e2aa4c686a82ea9bf0.png

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

9325a5ffd5d94f6fbff5844f0b90f179.png

测试:

用172.25.254.10测试

53494fd002ae45598114979fe07d6968.png

用172.25.254.20测试

06ff94c0f5bf479db5863e3c699c22fe.png

用172.25.254.1测试

d64de08d531541deafc1efbea5a76af2.png

d3335202ffd04b3eaa0fcd61c98cf92a.png

4.7ACL示例-匹配浏览器类型

7bc6f8fc03c645ff988ff71100e1bd43.png

测试:

拒绝访问

108adfa7dc20476c92516bd92c6676d7.png

可以访问

3f6b0a4b887947778b35a2ca58e6b9fd.png

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

[root@webserver1 ~]# dnf install php -y
[root@webserver1 ~]# systemctl restart httpd

[root@webserver1 ~]# vim /var/www/html/index.php

53a132f8ae734264bd20f1de20527613.png

设完这边要访问得到网页

50cb671d5a954baaafd7fb72cecb7e2d.png

9990bb29eed54d5482d64df0970cc92f.png

测试:

6b28e89c2b3c4867a2385d9dc649d055.png

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

[root@webserver1 ~]# mkdir -p /var/www/html/php
[root@webserver1 ~]# echo php - 172.25.254.10 > /var/www/html/php/inde.html
[root@webserver2 ~]# mkdir -p /usr/share/nginx/html/static
[root@webserver2 ~]# echo static - 172.25.254.20 > /usr/share/nginx/html/static/index.html

2940fbc196264781ac9249bf87e08feb.png

5、自定义HAProxy 错误界面

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

关掉两台后端主机的nginx或者http

编辑错误文件

[root@HAProxy conf.d]#  mkdir /haproxy/errorpages/ -p
[root@HAProxy conf.d]# cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
[root@HAProxy conf.d]#  vim /haproxy/errorpages/503page.http


d6915f62fb354fd6810c2e3124462124.jpeg编辑配置文件

0541ad8005cc4539af8149ae90980ccd.png

浏览器中测试:

1dd15d50ab8a4418b063f4f5c8a105b0.png

5.2 基于http重定向错误页面

a1b95153b5384f348ef86c73dbfd9401.png

再次在浏览器中访问就跳转到百度了

c68b87218b2b46119657880c529ae1a2.png

6、HAProxy 四层负载

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

MySQL 、Redis 、Memcache 、RabbitMQ

安装mariadb-server

编辑配置文件

427c925ff558430b8ba09dafe4191de5.png

5ac4c36bbc94456da40734be5f7c975e.png

49ec2ec9196c40b9a0e982b3c8aa2ca6.png

83c90970114244f3ab5a1255d7ed1ed6.png

添加远程登录用户

79ce03ce22cf413ca229158f353ed467.png

查看端口是否开启

01b600a7f09049ea885ea9fc996fb5d4.png

编辑配置文件

288d0049ecda4d32969166ce4a4a149d.png

测试远程登录:

073773b6589143408ea59eab91231934.png

7、HAProxy https 实现

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

7.1证书制作

70aea680d3cf431f88aa64e2e4f11a8a.png

编辑配置文件

10d7dfc433be41aaa06c384a974d17c6.png

浏览器访问

a8a6d99f7bb74235915f9b022a64186c.png

3a9d732caf434e289e6b765b8c845cec.png

查看证书

f845531c8e6e42b2aed92690b6c5ceb3.png

全站加密

c74d6ecb7f7c43c1ad384174b15be7f0.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值