目录
一、haproxy介绍
- 免费与开源:HAProxy作为一个免费的开源软件,提供了很多商业付费软件所具备的功能。
- 负载均衡能力:它支持L4 (TCP)和L7 (HTTP)两种负载均衡,能够根据不同需求进行选择。
- 会话保持:HAProxy能通过多种方式保持会话,例如基于客户端IP的Hash计算,或服务器发送的cookie。
- 虚拟主机支持:可以配置虚拟主机,以根据不同的域名或URL路径指向不同的后端服务器组。
- 高可用性:通过健康检查和状态监控,确保服务的持续性和可靠性。
- 多并发连接支持:HAProxy能够处理数以万计的并发连接,适用于大规模、高流量的网站和应用。
1.1 haproxy工作原理
其相关工作原理如下:
1.通过虚拟ur|或主机ip进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。
2.代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务器建立tcp连接。
3.支持7层代理的软件:
Nginx:基于http协议(nginx七层是通过proxy_pass)
Haproxy:七层代理,会话保持、标记、路径转移等。
- 非阻塞事件驱动引擎:HAProxy内部使用一个高效的事件驱动机制,这使得它能够在高并发场景下表现出色。
- 数据面优化:专注于数据的快速转发,尽可能减少数据处理的层级,将大部分工作放在内核中完成。
- 连接处理流程:处理传入连接时,HAProxy遵循一系列步骤,包括接受连接、应用规则、传递到后端、做出负载均衡决策、处理响应等。
- 健康检查与信息交换:定期检查后端服务器的健康状态,并可与其他HAProxy节点交换信息,以实现集群内的协调。
1.2 相关配置类型
全局配置:主要是配置相关进程及安全配置相关的参数 ,性能调整相关参数,Debug参数
proxies:代理配置段
- defaults:为frontend, backend, listen提供默认配置。为前端和后端提供默认的配置参数,这些参数可以被后续级别的配置覆盖
- frontend:前端,相当于nginx中的server {}。定义了客户端请求的接收方式以及如何将请求转发至后端服务器组
- backend:后端,相当于nginx中的upstream {}。指定了实际服务器的相关配置,如服务器列表、负载均衡策略等
- listen:同时拥有前端和后端配置,配置简单,生产推荐使用
二、全局配置
2.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.2实验示例
实验环境:
准备三台虚拟机,一台做haproxy负载配置,其他两台分别做web服务器配置。主机名分别设为haproxy(172.25.254.100),web1(172.25.254.10),web2(172.25.254.20)。相关实验环境配置如下,并且后面进行haproxy相关配置都是在此基础上
#web1和web2上配置nginx服务 [root@web1 ~]# dnf install nginx -y [root@web1 ~]# cat /usr/share/nginx/html/index.html webserver1-172.25.254.10 [root@web1 ~]# systemctl enable--now nginx [root@web2 ~]# dnf install nginx -y [root@web2 ~]# cat /usr/share/nginx/html/index.html webserver2-172.25.254.20 [root@web2 ~]# systemctl enable--now nginx #在haproxy上下载haproxy服务 [root@haproxy ~]# dnf install haproxy -y [root@haproxy ~]# systemctl enable--now haproxy
2.2.1 设置多进程
没设置之前先查看一下进程数:只有一个
设置我们是在配置文件里面设置:添加如下内容:
nbproc 2 # 启用多进程cpu-map 1 0 # 进程和 cpu 核心绑定防止 cpu 抖动从而减少系统资源消耗cpu-map 2 1 #2 表示第二个进程, 1 表示第二个 cpu 核心
就是如下图注意要在全局配置里面查看:
最后再查看一下进程数:就会有两个了
然后想要开启多线程就在后面添加 nbthread 2就行了,但是要注意其与多进程互斥,不能同时设置。 并且我们一般在企业中都是设置的多进程。
2.2.2 设置日志显示
在全局配置起日志作用的就是log 127.0.0.1 local2.如下图
这里我们需要在rsyslog配置文件中添加内容。------/etc/rsyslog.conf中添加
然后我们重启服务的时候就会自动报日志了。如下图
三、proxies代理配置
3.1 参数说明
参数 | 作用 |
defaults []
|
默认配置项,针对以下的
frontend
、
backend
和
listen生效,可以多个name
也可以没有
name
|
frontend
|
前端
servername
,类似于
Nginx
的一个虚拟主机
server
和
LVS服务集 群
|
backend
|
后端服务器组,等于
nginx
的
upstream
和
LVS
中的
RS
服务器
|
listen
|
将
frontend
和
backend
合并在一起配置,相对于
frontend
和
backend
配置更简洁,生产常用
|
3.2 default配置相关属性参数
3.2. 配置前端fronttend+后端backend
在配置文件/etc/haproxy/haproxy.cfg里面写配置:
#在/etc/haproxy/haproxy.cfg里面添加
frontend webcluster
bind *:80 #指定监听的地址
mode http
use_backend webcluster-host #调用backend名称
backend webcluster-host
balance roundrobin
server web1 172.25.254.10:80 #定义后端和端口real server 必须指定IP
server web2 172.25.254.20:80
其中后端配置的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的最大并发连接数
重启后再查看:就实现了负载均衡
3.3 配置listen项
在配置文件/etc/haproxy/haproxy.cfg里面写配置:
#vim /etc/haproxy/haproxy.cfg添加
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
重启测试查看:这个方法是将前后端合在一起的,其实现的效果和上面差不多
3.4 其他示例
3.4.1设置backup
在haproxy上面做:在httpd的配置文件里面将监听端口改成8080。
在配置文件中添加如下内容:
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
这个配置是当两台realserver出现故障时,才会起作用。
我们也可以server中添加disabled属性将real server设置为不能访问
3.4.2 redirect ---设定访问网页重定向
在配置文件中添加如下内容:将其重定向到百度上
redirect prefix http://www.baidu.com
listen webcluster
bind *:80
mode http
balance roundrobin
redirect prefix http://www.baidu.com
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
3.4.3 maxconn ----最大链接数
在配置文件中添加如下内容: maxconn 2
超过最大链接数就会出现backup现象
listen webcluster
bind *:80
mode http
balance roundrobin
server web1 172.25.254.10:80 maxconn 2 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
四、socat工具----热处理
其是一种动态调整haproxy工作方式参数,在配置文件/etc/haproxy/haproxy.cfg中位置如下
配置文件修改后要重启。
4.1 相关配置
然后我们来下载socat工具,并且写一些命令配置:
#下载工具
[root@haproxy ~]# dnf install socat -y
#查看socat工具帮助
[root@haproxy ~]# echo "help" | socat stdio /var/lib/haproxy/stats
#查看进程状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
#查看权重
[root@haproxy ~]# echo get weight webcluster/web1 | socat stdio /var/lib/haproxy/stats
#修改权重
[root@haproxy ~]# echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats
#下线后端服务器
[root@haproxy ~]# echo "disable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
#上线后端服务器
[root@haproxy ~]# echo "enable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
4.2 设置多进程
如果开启多进程那么我们在对进程的sock文件进行操作时其对进程的操作时随机的
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket #添加这个设置多个进程文件 stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1 stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2 # utilize system-wide crypto-policies ssl-default-bind-ciphers PROFILE=SYSTEM ssl-default-server-ciphers PROFILE=SYSTEM #开启多进程 nbproc 2 cpu-map 1 0 cpu-map 2 1
重启服务,测试查看:
就会出现多个进程文件
五、haproxy算法
HAProxy 通过固定参数 balance 指明对后端服务器的调度算法balance 参数可以配置在 listen 或 backend 选项中。HAProxy 的调度算法分为静态和动态调度算法有些算法可以根据参数在静态和动态算法中相互转换。
5.1 静态算法
5.1.1 static-rr:基于权重的轮询调度
- 不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
- 不支持端服务器慢启动
- 其后端主机数量没有限制,相当于LVS中的 wrr
慢启动是指在服务器刚刚启动上不会把他所应该承担的访问压力全部给它,而是先给一部分,当没问题后在给一部分
在配置文件中 添加balance static-rr:
listen webcluster
bind *:80
mode http
#添加static-rr
balance static-rr
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
5.1.2 first
- 根据服务器在列表中的位置,自上而下进行调度
- 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
- 其会忽略服务器的权重设置
- 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
在配置文件中 添加balance first:
listen webcluster
bind *:80
mode http
#添加first
balance first
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
最后用socat进行修改权重时,发现无法修改。
5.2 动态算法
动态算法就是
- 基于后端服务器状态进行调度适当调整,
- 新请求将优先调度至当前负载较低的服务器
- 权重可以在haproxy运行时动态调整无需重启
5.2.1 roundrobin
- 基于权重的轮询动态调度算法,
- 支持权重的运行时调整,不同于lvs中的rr轮训模式,
- HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),
- 其每个后端backend中最多支持4095个real server,
- 支持对real server权重动态调整,
- roundrobin为默认调度算法,此算法使用广泛
listen webcluster
bind *:80
mode http
#添加roundrobin
balance roundrobin
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
测试: 发现可以修改权重
[root@haproxy ~]# echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats
5.2.2 leastconn---基于链接非权重
- leastconn加权的最少连接的动态
- 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
- 比较适合长连接的场景使用,比如:MySQL等场景。
listen webcluster
bind *:80
mode http
#添加leastconn
balance leastconn
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
5.3 其他算法
5.3.1 source
源地址 hash ,基于用户源地址 hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一 个后端 web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过 hash-type 支持的选项更改这个算法一般是在不插入 Cookie 的TCP模式下使用,也可给拒绝会话 cookie 的客户提供最好的会话粘性,适用于 session会话保持但不支持 cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性 hash
5.3.1.1 map-base 取模法
- map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。
- 此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度
- 缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变
所谓取模运算,就是计算两个数相除之后的余数, 10%7=3, 7%4=3map-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 ----- > nodeb1112 ------> nodec1113 ------> nodea如果 a 下线后,权重数量发生变化1111%2=1 , 1112%2=0 , 1113%2=11112 和 1113 被调度到的主机都发生变化,这样会导致会话丢失
在配置文件中配置如下:
listen webcluster
bind *:80
mode http
#添加source
balance source
hash-type map-base
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
测试:
#不支持动态调整权重值
[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)
5.3.1.2 一致性hash
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动 hash ( o) mod n该 hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动
具体算法:
- 后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)
- 客户机哈希环点key1=hash(client_ip)%(2^32) 得到的值在[0---4294967295]之间,
- 将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
会产生hash环偏斜问题:
通过增加虚拟服务器 IP 数量,比如:一个后端服务器根据权重为 1 生成 1000 个虚拟 IP ,再 hash。而后端服务器权重为 2 则生成 2000 的虚拟 IP ,再 bash, 最终在 hash 环上生成 3000 个节点,从而解决 hash 环偏斜问题。
![](https://i-blog.csdnimg.cn/direct/3ed5d9d5bb6842c5b222abb8f8948c6e.png)
![](https://i-blog.csdnimg.cn/direct/62fa71c73b114e909bc177df2b30ed96.png)
listen webcluster
bind *:80
mode http
#添加source
balance source
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
5.3.2 uri
语法:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>左半部分: /<path>;<params>整个 uri : /<path>;<params>?<query>#<frag>
uri取模法示例:
listen webcluster
bind *:80
mode http
balance uri
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
与hash一致性一起使用:
listen webcluster
bind *:80
mode http
balance uri
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
测试访问:创建不同的文件当作uri
[root@web1 ~]# curl 172.25.254.100/index2.html
172.25.254.20 ---index2.html
[root@web1 ~]# curl 172.25.254.100/index3.html
172.25.254.10 ---index3.html
[root@web1 ~]# curl 172.25.254.100/index1.html
172.25.254.20 ---index1.html
5.3.3 url_param
url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash计算,并由服务器 总权重相除以后派发至某挑出的服务器 ,后端搜索同一个数据会被调度到同一个服务器,多用与电商,通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server如果无没 key ,将按 roundrobin 算法
配置如下:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
#添加
listen webcluster
bind 172.25.254.100:80
mode http
balance url_param name,userid #支持对多个url_param hash
hash-type consistent
server web1 172.25.254.10:80 weight 1 check inter 3s fall 3 rise 5
server web2 172.25.254.20:80 weight 1 check inter 3s fall 3 rise 5
测试:
[root@web1 ~]# curl 172.25.254.100/index1.html?name=lee
172.25.254.20 ---index1.html
[root@web1 ~]# curl 172.25.254.100/index1.html?name=lee
172.25.254.10 ---index1.html
[root@web1 ~]# curl 172.25.254.100/index1.html?name=test
172.25.254.20 ---index1.html
[root@web1 ~]# curl 172.25.254.100/index1.html?name=test
172.25.254.20 ---index1.html
5.3.4 hdr
针对用户每个http头部(header)请求中的指定信息做hash,
此处由 name 指定的 http 首部将会被取出并做 hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
配置:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
mode http
balance hdr(Usr-Agent)
hash-type consistent
server web1 172.25.254.10:80 check inter 2 fall 3 rise 5 weight 1
server web2 172.25.254.20:80 check inter 2 fall 3 rise 5 weight 1
server web_sorry 172.25.254.100:8080 backup
测试
#测试查看
curl -v 172.25.254.100
curl -vA "firefox" 172.25.254.100
curl -vA "sougou" 172.25.254.100
5.4 算法总结
#静态
static-rr--------->tcp/http
first------------->tcp/http
#动态
roundrobin-------->tcp/http
leastconn--------->tcp/http
#以下静态和动态取决于hash_type是否consistent
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
使用场景
first #使用较少
static-rr #做了session共享的web集群
roundrobin
leastconn #数据库
source
#基于客户端公网IP的会话保持
Uri--------------->http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http #可以实现session保持
hdr #基于客户端请求报文头部做下一步处理