haproxy七层代理
前言
haproxy是一款高性能的 TCP 和 HTTP 负载均衡器与代理服务器,在学习haproxy之前我们先了解一下什么是负载均衡。
所谓负载均衡(Load Balance,简称LB),是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。
负载均衡的好处
- 业务扩展与用户体验
实现Web服务器动态水平扩展,新增或减少服务器时,通过负载均衡自动分配流量,用户无感知,保障业务连续性与稳定性,像电商大促扩容服务器,用户访问不受影响。 - 并发处理能力
把大量并发请求分散到多台服务器,突破单服务器性能瓶颈。例如社交平台高峰时段,多服务器协同处理,避免服务卡顿/崩溃,提升系统并发处理效率。 - 成本控制
多后端服务器可共享少量公网IP对外服务,减少IP地址采购、管理成本,尤其对服务器规模大的企业,能显著节约IT支出。 - 安全防护
客户端请求先到负载均衡器,再转发给内部服务器,隐藏真实IP,降低内部服务器被直接攻击(如扫描、恶意访问 )的风险,增强系统安全性。 - 运维便捷性
基于固定格式配置文件,参数设置、服务器增减、算法选择等操作简单,降低运维门槛,经验少的运维人员也能快速部署、管理。 - 功能灵活性
支持四层(TCP/UDP等传输层协议 )、七层(HTTP/HTTPS等应用层协议 )负载均衡,适配不同业务场景;还能动态下线故障主机,通过健康检查自动移除异常服务器,恢复后再添回,保障流量仅流向健康节点。 - 高性能支撑
可承载数万甚至数十万并发请求,满足大型在线游戏、金融交易等高并发场景需求,稳定分配流量,确保系统高效运行。
负载均衡的分类
按网络层次分类
四层负载均衡(传输层,对应 OSI 第四层)
工作原理:基于 “传输层协议 + 端口” 转发请求,仅解析数据包的源 IP、目标 IP、源端口、目标端口(如 TCP/UDP 协议信息),不关心应用层内容(如 HTTP 请求的具体路径、参数)。
典型场景:需要高性能转发的场景,如数据库集群(MySQL 主从架构)、TCP 长连接服务(即时通讯)、游戏服务器等。
优势:转发效率极高(无需解析应用层数据),适合高并发、低延迟需求。
代表工具:LVS(Linux Virtual Server)、F5 硬件负载均衡器(四层模式)。七层负载均衡(应用层,对应 OSI 第七层)
工作原理:基于 “应用层协议内容” 转发请求,会解析应用层数据(如 HTTP 的 URL、请求头、Cookie,HTTPS 的域名等),能实现更精细的流量分配。
典型场景:Web 应用(网站、API 服务)、需要按内容分流的场景(如将图片请求转发到图片服务器,动态页面请求转发到应用服务器)。
优势:支持基于应用内容的灵活调度(如 URL 路由、会话保持),功能更贴合 Web 业务需求。
代表工具:Nginx、HAProxy(七层模式)、云厂商的应用负载均衡(如阿里云 ALB)。
这两类是目前企业级应用中最常用的,核心区别在于 “基于什么信息转发请求”。
*1.分层位置:四层负载均衡在传输层及以下,七层负载均衡在应用层及以下*
*2.性能 :四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高:七层可支持解析应用*
*层报文消息内容,识别URL、Cookie、HTTP header等信息。、*
*3.原理 :四层负载均衡是基于ip+port;七层是基于虚拟的URL或主机IP等。*
*4.功能类比:四层负载均衡类似于路由器;七层类似于代理服务器。*
*5.安全性:四层负载均衡无法识别DDoS攻击;七层可防御SYN Cookie/Flood攻击*
按设备类型分类
硬件负载均衡器:是一种专门的网络设备,通常由专业厂商生产,如 F5 Big - IP、A10 Networks 等。硬件负载均衡器性能强大,能够处理大量的并发请求,具备高可用性、可靠性和丰富的功能特性,如 SSL 卸载、会话保持、应用层防火墙等。但价格相对昂贵,且后期的维护和升级成本较高,一般适用于对性能、稳定性要求极高,且预算充足的大型企业或数据中心。
软件负载均衡器:通过软件程序实现负载均衡功能,常见的有 LVS(Linux Virtual Server)、HAProxy、Nginx 等。软件负载均衡器可以运行在普通的服务器上,成本较低,且具有较高的灵活性,用户可以根据自身需求进行定制和扩展。虽然在处理性能上可能不如硬件负载均衡器,但在很多中、小型企业以及互联网应用场景中,软件负载均衡器能够很好地满足需求,同时还便于与现有的服务器和网络架构进行集成。
haproxy简介
定位:开源高性能负载均衡器与反向代理服务器(C 语言开发)。
核心功能:
支持 4 层(TCP) 和 7 层(HTTP/HTTPS) 负载均衡,算法丰富(轮询、最少连接等)。
实时健康检查,自动摘除 / 恢复故障服务器。
SSL/TLS 终止与加速,减轻后端服务器加密负担。
会话保持(基于 Cookie/IP 哈希),确保用户会话连续性。
优势:轻量高效(单实例支持百万并发)、配置灵活、社区活跃。
典型场景:Web 服务负载均衡、微服务 API 网关、数据库读写分离、云原生环境流量分发。
代表用户:GitHub、Stack Overflow、Twitter 等。
对比:性能接近硬件负载均衡器(如 F5),但成本更低,适合中大型互联网应用。
haproxy的安装和服务信息
实验环境
主机名 | IP | 作用 |
---|---|---|
client | 192.168.0.10 | 作为客户端进行访问测试 |
haproxy | 192.168.1.100;192.168.0.100 | 作为代理服务器根据算法进行调度 |
rs1 | 192.168.1.101 | 后端server1 |
rs1 | 192.168.1.102 | 后端server2 |
软件包的安装
[root@haproxy ~]# yum install haproxy -y
相关参数信息
软件安装包: haproxy-2.4.22-3.el9_3.x86_64.rpm
启动文件: /lib/systemd/system/haproxy.service
主配置目录: /etc/haproxy/
主配置文件: /etc/haproxy/haproxy.cfg
子配置目录: /etc/haproxy/conf.d
启用多进程和多线程
多进程
查看haproxy进程及子进程
[root@haproxy ~]# pstree -p | grep haproxy
默认情况下
开启多进程后
开启方法(修改主配置文件添加参数)
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
nbproc 2 #启用2个进程(不指定时默认为一个)
cpu-map 1 0 #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
cpu-map 2 1 #2表示第二个进程,1表示第二个cpu核心
多线程
开启方法(修改主配置文件添加参数)
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
nbthread 2 #指定haproxy的线程数量,默认每个进程一个线程,此参数与nbproc互斥
查看
未开启多线程
[root@haproxy ~]# cat /proc/xxxx(haproxy子进程id)/status
...上面内容省略...
Threads: 1
...下面内容省略...
开启后
[root@haproxy ~]# cat /proc/xxxx(haproxy子进程id)/status
...上面内容省略...
Threads: 2
...下面内容省略...
proxies配置示例
方法一
在主配置文件中进行编辑
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webserver
bind 192.168.0.100:80
mode http
use_backend web-rs
backend web-rs
mode http
server web1 192.168.1.101:80 check inter 3s fall 3 rise 5
server web2 192.168.1.102:80 check inter 3s fall 3 rise 5
#frontend:前端,相当于nginx中的server {}
#backend:后端,相当于nginx中的upstream {}
测试
[root@client ~]# for i in {1..10} ;do curl 192.168.0.100 ;done
方法二
在主配置文件中进行编辑
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 192.168.0.100:80
mode http
server web1 192.168.1.101:80 check inter 3s fall 3 rise 5
server web2 192.168.1.102:80 check inter 3s fall 3 rise 5
#将frontend和backend合并在一起配置,相对于frontend和backend配置更简洁,生产常用
测试如下
socat工具
对服务器动态权重和其它状态可以利用 socat工具进行调整
#修改主配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
#安装
[root@haproxy ~]# yum search socat -y
#调出帮助
[root@haproxy ~]# echo "help" | socat stdio /var/lib/haproxy/haproxy.sock1
socat的使用
#查看haproxy的状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/haproxy.sock1
#查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/haproxy.sock1
#查看指定服务器权重
[root@haproxy ~]# echo "get weight webserver/web1" | socat stdio /var/lib/haproxy/haproxy.sock1
#修改权重
[root@haproxy ~]# echo "set weight webserver/web1 2" | socat stdio /var/lib/haproxy/haproxy.sock1
#下线后端指定服务器
[root@haproxy ~]# echo "disable server webserver/web1" | socat stdio /var/lib/haproxy/haproxy.sock1
#上线后端指定服务器
[root@haproxy ~]# echo "enable server webserver/web1" | socat stdio /var/lib/haproxy/haproxy.sock1
注:在多进程时,我们可以对单独的sock文件进行单独管理
haproxy的状态页
#编辑主配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:8888
stats enable
log global
stats uri /haproxy-status #设置的访问路径
stats auth ch:ch #这是设置的账户和密码
#相关参数
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中的管理功能
在浏览器访问
#pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
pid = 27134 (process #1, nbproc = 1, nbthread = 1)
#启动了多长时间
uptime = 0d 0h00m04s
#系统资源限制:内存/最大打开文件数/
system limits: memmax = unlimited; ulimit-n = 200029
#最大socket连接数/单进程最大连接数/最大管道数maxpipes
maxsock = 200029; maxconn = 100000; maxpipes = 0
#当前连接数/当前管道数/当前连接速率
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps
#运行的任务/当前空闲率
Running tasks: 1/14; idle = 100 %
active UP: #在线服务器
backup UP: #标记为backup的服务器
active UP, going down: #监测未通过正在进入down过程
backup UP, going down: #备份服务器正在进入down过程
active DOWN, going up: #down的服务器正在进入up过程
backup DOWN, going up: #备份服务器正在进入up过程
active or backup DOWN: #在线的服务器或者是backup的服务器已经转换成了down状态
not checked: #标记为不监测的服务器
#active或者backup服务器人为下线的
active or backup DOWN for maintenance (MAINT)
#active或者backup被人为软下线(人为将weight改成0)
active or backup SOFT STOPPED for maintenance
session rate(每秒的连接会话信息): Errors(错误统计信息):
cur:每秒的当前会话数量 : Req:错误请求量
max:每秒新的最大会话数量 conn:错误链接量
limit:每秒新的会话限制量 Resp:错误响应量
sessions(会话信息): Warnings(警告统计信息):
cur:当前会话量 Retr:重新尝试次数
max:最大会话量 Redis:再次发送次数
limit: 限制会话量
Total:总共会话量 Server(real server信息):
LBTot:选中一台服务器所用的总时间 Status:后端机的状态,包括UP和DOWN
Last:和服务器的持续连接时间 LastChk:持续检查后端服务器的时间
Wght:权重
Bytes(流量统计): Act:活动链接数量
In:网络的字节输入总量 Bck:备份的服务器数量
Out:网络的字节输出总量 Chk:心跳检测时间
Dwn:后端服务器连接后都是DOWN的数量
Denied(拒绝统计信息): Dwntme:总的downtime时间
Req:拒绝请求量 Thrtle:server 状态
Resp:拒绝回复
haproxy的算法
HAProxy通过固定参数 balance 指明对后端服务器的调度算法,balance参数可以配置在listen或backend选项中。
HAProxy的调度算法分为静态和动态调度算法,有些算法可以根据参数在静态和动态算法中相互转换。
静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
static-rr(基于权重的轮询调度)
不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
不支持端服务器慢启动
其后端主机数量没有限制,相当于LVS中的 wrr
配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 192.168.0.100:80
mode http
balance static-rr
server web1 192.168.1.101:80 weight 2 check inter 3s fall 3 rise 5
server web2 192.168.1.102:80 weight 1 check inter 3s fall 3 rise 5
测试
[root@client ~]# for i in {1..10} ; do curl 192.168.0.100 ;done
first(首先只访问第一台,直到其业务处理不过来)
根据服务器在列表中的位置,自上而下进行调度
其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
其会忽略服务器的权重设置
不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
#配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 192.168.0.100:80
mode http
balance first
server web1 192.168.1.101:80 maxconn 3 check inter 3s fall 3 rise 5
server web2 192.168.1.102:80 check inter 3s fall 3 rise 5
测试
[root@client ~]# while true ; do curl 192.168.0.100 ; sleep 0.1 ;done
#在两台主机上分别执行此循环,可以观察是否102被调度到
while true;do curl 192.168.0.100 ; sleep 0.1;done
动态算法
基于后端服务器状态进行调度适当调整,新请求将优先调度至当前负载较低的服务器,权重可以在haproxy运行时动态调整无需重启。
roundrobin
1. 基于权重的轮询动态调度算法,
2. 支持权重的运行时调整,不同于lvs中的rr轮训模式,
3. HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),
4. 其每个后端backend中最多支持4095个real server,
5. 支持对real server权重动态调整,
6. roundrobin为默认调度算法,此算法使用广泛
#配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 192.168.0.100:80
mode http
balance roundrobin
server web1 192.168.1.101:80 weight 2 check
server web2 192.168.1.102:80 weight 1 check
测试
使用socat动态调整权值后再测试
[root@haproxy ~]# echo "get weight webserver/web1 " | socat stdio /var/lib/haproxy/haproxy.sock1
2 (initial 2)
[root@haproxy ~]# echo "set weight webserver/web1 1" | socat stdio /var/lib/haproxy/haproxy.sock1
[root@haproxy ~]# echo "get weight webserver/web1 " | socat stdio /var/lib/haproxy/haproxy.sock1
1 (initial 2)
leastconn(加权的最少连接)
leastconn加权的最少连接的动态
支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
比较适合长连接的场景使用,比如:MySQL等场景。
#配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver
bind 192.168.0.100:80
mode http
balance leastconn
server web1 192.168.1.101:80 weight 2 check
server web2 192.168.1.102:80 weight 1 check
#我们配置的权重为2:1,那么后端在访问时会按此进行访问,但是算法为leastconn,会基于当前最少连接进行调整
测试
其他算法
- 取模法(map-base 取模)
原理:
server_index = hash(key) % N
- `N` 是服务器数量。
- 每个 key 通过哈希后取模,决定落到哪台服务器。
优点:简单、计算快、均匀分布。
缺点:服务器数量变化时(扩容/缩容),几乎所有 key 都会重新映射,导致大规模缓存失效或连接漂移。
- 一致性哈希(Consistent Hashing)
原理:
- 构建一个**哈希环**(0 ~ 2^32-1)。
- 服务器节点通过哈希分布在环上。
- key 也哈希后落在环上,顺时针找最近的服务器节点(就近访问原则)。
- 为避免数据倾斜,每个物理节点可对应多个**虚拟节点(vnode)。
优点:
- 当节点增减时,**只影响环上相邻的一小段数据**,迁移量小。
- 更适合**分布式缓存、负载均衡、持久连接场景**。
示例:
假设有一个分布式缓存系统,使用 3 台服务器(A、B、C)存储用户会话数据,需要将用户请求路由到对应的缓存服务器。用户 ID 作为路由键(如用户 ID 为 1001 的请求,需路由到存储该用户会话的服务器)。
一、传统取模法示例(hash(用户ID) % 服务器数量)
1. 初始状态(3 台服务器)
服务器列表:A、B、C(编号 0、1、2)
路由规则:用户ID % 3
示例请求:
用户 ID=1001 → 1001 % 3 = 2 → 路由到服务器 C
用户 ID=1002 → 1002 % 3 = 0 → 路由到服务器 A
用户 ID=1003 → 1003 % 3 = 1 → 路由到服务器 B
2. 服务器扩容(新增服务器 D)
服务器列表:A、B、C、D(编号 0、1、2、3)
路由规则:用户ID % 4
示例请求重新路由:
用户 ID=1001 → 1001 % 4 = 1 → 从服务器 C 改为服务器 B
用户 ID=1002 → 1002 % 4 = 2 → 从服务器 A 改为服务器 C
用户 ID=1003 → 1003 % 4 = 3 → 从服务器 B 改为服务器 D
结论:仅新增 1 台服务器,但几乎所有用户请求的路由都发生变化,导致大量缓存失效(需重新加载数据到新服务器)。
二、一致性哈希示例(虚拟环 + 虚拟节点)
Ⅰ. 初始状态(3 台服务器,每台 5 个虚拟节点)
虚拟环:0~2^32-1(简化为 0~100)
服务器虚拟节点分布(假设哈希值):
服务器 A:10、25、40、55、70
服务器 B:15、30、45、60、75
服务器 C:20、35、50、65、80
Ⅱ. 请求路由过程
用户 ID=1001 → 计算哈希值(假设为 62):
沿环顺时针查找,62 落在 60(B)和 65(C)之间 → 路由到服务器 C
用户 ID=1002 → 哈希值 = 22:
22 落在 20(C)和 25(A)之间 → 路由到服务器 A
用户 ID=1003 → 哈希值 = 32:
32 落在 30(B)和 35(C)之间 → 路由到服务器 C
Ⅲ. 服务器扩容(新增服务器 D,5 个虚拟节点)
新增虚拟节点(假设哈希值):
服务器 D:5、23、48、68、85
请求路由变化:
用户 ID=1001(哈希值 = 62):
原路由:60(B)→65(C)→ 服务器 C
现路由:60(B)→65(C)→ 服务器 C(不变)
用户 ID=1002(哈希值 = 22):
原路由:20(C)→25(A)→ 服务器 A
现路由:20(C)→23(D)→ 服务器 D(变化)
用户 ID=1003(哈希值 = 32):
原路由:30(B)→35(C)→ 服务器 C
现路由:30(B)→35(C)→ 服务器 C(不变)
结论:新增 1 台服务器后,仅部分用户请求的路由发生变化(如用户 1002),大部分请求仍保持原路由,缓存命中率显著提高。
特性 | 取模法 | 一致性哈希 |
---|---|---|
算法复杂度 | 低 | 中等(需维护哈希环) |
节点扩容影响 | 高(大量重映射) | 低(只影响相邻节点) |
数据分布 | 均匀 | 可调节(虚拟节点) |
是否支持动态伸缩 | ❌ 不支持 | ✅ 支持 |
典型应用 | 简单缓存、静态分片 | Redis Cluster、HAProxy、CDN |
- source(源地址哈希)
hash-type = consistent(一致性哈希)
工作原理:基于客户端的源IP地址,通过一致性哈希算法映射到哈希环上,使得来自同一个源IP地址的请求尽可能被转发到同一个后端服务器。当后端服务器数量发生变化时(如新增或移除服务器),只有少量请求会被重新分配到其他服务器,而不是所有请求都重新分配。
应用场景:适用于希望为特定客户端提供会话保持功能的场景,例如在线购物网站,让同一个用户的多次请求都能由同一台后端服务器处理,保证用户会话的连续性。
特性:具备较好的扩展性和稳定性,能减少因后端服务器变化导致的请求重分配,从而降低后端服务器的负载抖动。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http hash-type consistent #添加此参数为一致性哈希,不添加默认为传统取模 balance source server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
hash-type = map-based(取模哈希)
工作原理:对客户端的源IP地址进行取模运算,将其映射到后端服务器列表中的某一台服务器。如果后端服务器数量为N,那么通过对源IP地址的哈希值取模N,得到的结果就是对应的后端服务器索引。当后端服务器数量变化时,大部分请求都会被重新分配到不同的服务器。
应用场景:在后端服务器数量相对固定,且对会话保持有一定需求的场景下可以使用。不过,由于后端服务器数量变化会导致大量请求重新分配,所以适用于后端服务器规模比较稳定的环境。
特性:实现简单,但灵活性和稳定性较差,当后端服务器数量变动时,请求分配的变化较大,可能会导致后端服务器负载的大幅波动。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http balance source server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
- uri(URI哈希)
hash-type = consistent(一致性哈希)
工作原理:对请求的URI(即
?
前面的部分)进行一致性哈希计算,将相同URI的请求映射到哈希环上的特定位置,进而转发到对应的后端服务器。与源地址哈希类似,在后端服务器数量变化时,只有部分与变动相关的URI请求会被重新分配。应用场景:适合对特定资源的请求进行固定分配的场景,比如对于网站中某些经常被访问的静态资源(如CSS、JavaScript文件),可以通过URI哈希确保它们始终由同一台后端服务器提供服务,提高缓存命中率和响应速度。
特性:能有效保持相同资源请求的分配一致性,并且在后端服务器变更时对请求分配的影响相对较小,有利于维持后端服务的稳定性。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http hash-type consistent balance uri server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
hash-type = map-based(取模哈希)
工作原理:对URI进行取模运算,根据取模结果决定将请求转发到哪一台后端服务器。后端服务器数量的改变会直接影响取模结果,从而导致大量请求的分配发生变化。
应用场景:适用于后端服务器数量固定且对URI请求分配有一定规则要求的场景,例如在一个小型的文件下载服务器集群中,根据文件URI来分配请求。但如果后端服务器数量经常变动,可能会导致请求分配的混乱。
特性:简单直接,但在后端服务器数量变动时缺乏灵活性,容易造成请求分配的不均衡和不稳定。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http balance uri server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
- url_param(URL参数哈希)
hash-type = consistent(一致性哈希)
工作原理:针对URL中
?
后面的参数部分(即查询字符串),通过一致性哈希算法进行处理。例如,如果请求的URL参数中包含用户ID,那么同一个用户ID的请求会被映射到哈希环上的固定位置,从而被转发到同一台后端服务器。在后端服务器增减时,只有与变动相关的参数请求会被重新分配。应用场景:常用于需要根据用户特定标识(如用户ID、会话ID等)进行请求分配的场景,比如社交平台,根据用户ID将用户的请求固定分配到某一台服务器,便于管理用户会话和缓存用户相关数据。
特性:能够精准地实现基于特定参数的会话保持,并且在后端服务器结构变化时,对请求分配的影响相对有限,保证了服务的稳定性和连续性。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http hash-type consistent balance url_param name server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
hash-type = map-based(取模哈希)
工作原理:对URL参数部分进行取模运算,依据取模结果将请求分配到不同的后端服务器。后端服务器数量的改变会使得取模结果改变,进而导致大量请求被重新分配到不同的服务器。
应用场景:在后端服务器数量稳定,且希望根据URL参数进行简单请求分配的场景下使用。例如,在一个简单的电商促销活动页面,根据请求URL中的促销活动参数来分配请求到不同的后端服务器处理。但如果后端服务器数量变化频繁,会导致请求分配的不稳定。
特性:实现较为简单,但在后端服务器数量变动时,请求分配的调整幅度较大,可能会影响服务的稳定性和用户体验。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http balance url_param name server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
- hdr(HTTP头部哈希)
hash-type = consistent(一致性哈希)
工作原理:根据HTTP报文中的头部信息(如
User-Agent
、Cookie
等),通过一致性哈希算法进行计算,将具有相同头部信息特征的请求映射到哈希环上的固定位置,从而转发到同一台后端服务器。当后端服务器数量变化时,只有部分相关请求会被重新分配。应用场景:适用于需要根据客户端的特定属性(如浏览器类型、用户登录状态等)进行请求分配的场景。比如,对于某些特定浏览器版本的用户请求,将它们固定分配到某一台服务器,以便进行针对性的功能测试或优化。
特性:能够根据丰富的客户端信息进行灵活的请求分配,并且在后端服务器变动时,能较好地保持请求分配的稳定性,减少对后端服务的冲击。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http hash-type consistent balance hdr(User-Agent) server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
hash-type = map-based(取模哈希)
工作原理:对HTTP头部信息进行取模运算,根据取模结果决定请求转发到哪一台后端服务器。后端服务器数量的改变会直接影响取模结果,进而导致大量请求被重新分配到不同的服务器。
应用场景:在后端服务器数量固定,且需要根据HTTP头部简单区分请求的场景下使用。例如,根据
User-Agent
头部区分不同浏览器的请求并分配到不同的后端服务器进行处理。但如果后端服务器数量经常变化,会导致请求分配的频繁调整。特性:实现相对简单,但在后端服务器数量变动时,请求分配的灵活性和稳定性较差,可能会影响后端服务器的负载均衡和服务质量。
#配置示例 [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg listen webserver bind 192.168.0.100:80 mode http balance hdr(User-Agent) server web1 192.168.1.101:80 check server web2 192.168.1.102:80 check
测试
总结
静态算法
算法 协议支持 核心逻辑 特点 static-rr TCP/HTTP 基于服务器权重的固定轮询(权重通过 weight
参数设置)。 例如:服务器 A (weight=2)、B (weight=1) → 请求按 A-A-B 循环分发。- 适合服务器性能差异较大的场景; - 服务器权重调整后需重启 HAProxy 生效。 first TCP/HTTP 按配置文件中服务器的顺序,优先将请求分发给第一个 健康 的服务器。 - 简单直接,但可能导致单服务器过载; - 常用于主备模式(如主数据库优先)。 动态算法
roundrobin TCP/HTTP 简单轮询,按顺序依次分发请求(不考虑服务器权重)。 - 实现简单,适用于服务器性能相近的场景; - 不感知服务器负载变化。 leastconn TCP/HTTP 将请求分发给当前 连接数最少 的服务器(动态计算)。 - 适合长连接场景(如数据库连接、SSH); - 避免连接数不均导致的过载。 其他算法
算法 协议支持 核心逻辑 静态 / 动态取决于 hash-type
参数source TCP/HTTP 基于客户端 IP 地址哈希(如 hash(IP) % 服务器数
)。- 静态(默认):服务器变更时大量请求重新路由; - 动态( hash-type consistent
):仅影响相邻区间。uri HTTP 基于请求的 URI 哈希(如 /api/user/1001
)。- 适合缓存场景(同一资源总是路由到同一服务器)。 url_param HTTP 基于 URL 参数哈希(如 ?session_id=xxx
或?user_id=1001
)。- 适合会话保持或用户数据分区(如分布式缓存)。 hdr HTTP 基于 HTTP 请求头哈希(如 hdr(Cookie)
、hdr(Host)
)。- 灵活度高,可根据业务自定义哈希键(如用户 ID、租户 ID)。
高级功能及配置
基于cookie的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址hash调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
#配置示例
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80
option forwardfor
mode http
balance roundrobin
cookie WEBCOOKIE insert nocache indirect
server webserver1 192.168.0.101:80 cookie web1 weight 1 check inter 3s fall
3 rise 5
server webserver2 192.168.0.102:80 cookie web2 weight 1 check inter 3s fall
3 rise 5
测试
IP透传
web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景
七层IP透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
ACL访问控制
是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许其通过或丢弃。