HAProxy
HAProxy(High Availability Proxy)是一款高性能、开源的负载均衡器与反向代理服务器,主要用于 TCP 和 HTTP 协议的流量分发,同时具备强大的高可用、健康检查和流量控制能力。它广泛应用于高并发 Web 服务、API 网关、数据库代理等场景,以轻量、高效、稳定著称,是企业级架构中常用的流量调度组件。
一、核心特性
- 多协议支持
- 支持HTTP/HTTPS(七层代理):可基于 URL、域名、Cookie 等应用层信息转发请求。
- 支持TCP(四层代理):适用于 MySQL、Redis、SSH 等基于 TCP 的服务负载均衡。
- 支持 WebSocket、gRPC 等新兴协议,兼容现代应用架构。
- 高性能与低资源消耗
- 采用单进程、多线程模型(默认),结合事件驱动(epoll/kqueue)机制,处理并发连接能力极强(单实例可支撑数十万并发)。
- 内存占用低(通常仅数 MB),CPU 利用率高效,适合部署在资源受限的环境中。
- 灵活的负载均衡算法
针对不同场景提供多种调度策略: - 强大的健康检查
- 支持主动检查(定期向后端服务器发送探测请求,如 HTTP GET、TCP 连接)和被动检查(监控后端服务器的响应状态码、超时等)。
- 当后端服务器故障时,自动将其从集群中剔除;恢复后自动重新加入,无需人工干预。
- 可自定义检查频率、超时时间、健康阈值等参数,适配不同服务的特性(如 MySQL 需检查端口连通性 + SQL 语句执行结果)。
- 会话保持与高可用
- 通过 Cookie、源地址哈希等方式实现会话绑定,确保用户会话在同一后端服务器上延续(需后端服务不支持分布式会话时使用)。
- 可与 Keepalived、Heartbeat 等工具结合,实现 HAProxy 自身的主从切换,避免单点故障,保障负载均衡层的高可用。
- 流量控制与安全防护
- 支持速率限制(如限制单个 IP 的请求频率),防止 DDoS 攻击或恶意请求。
- 可过滤恶意 HTTP 请求(如特定 User-Agent、请求头),屏蔽危险 URL 或参数。
- 支持 SSL/TLS 终止(HTTPS 卸载),在 HAProxy 层解密 HTTPS 请求,减轻后端服务器的加密 / 解密压力。
- 详细的日志与监控
- 记录完整的请求日志(包括客户端 IP、请求时间、后端服务器、响应状态码、响应时间等),便于问题排查和性能分析。
- 提供内置统计页面(通过配置启用),实时展示后端服务器状态、连接数、流量等指标,支持与 Prometheus、Grafana 等监控工具集成。
二、工作原理
HAProxy 的核心工作流程可分为前端(Frontend) 和后端(Backend) 两部分,通过配置文件定义规则,实现流量的接收、转发和处理:
- 前端(Frontend):
- 负责接收客户端请求,绑定监听端口(如 80 端口接收 HTTP 请求,443 端口接收 HTTPS 请求)。
- 基于预设规则(如域名、URI、客户端 IP)对请求进行过滤或分类,决定将请求转发到哪个后端集群。
- 后端(Backend):
- 定义一组后端服务器(如 Web 服务器集群、MySQL 集群)的 IP 和端口。
- 配置负载均衡算法、健康检查规则、会话保持策略等。
- HAProxy 根据前端规则和后端配置,将请求转发到合适的后端服务器,并将响应结果返回给客户端。
简单来说,HAProxy 就像一个 “智能流量调度员”:客户端请求先到 HAProxy(前端),HAProxy 根据规则判断 “该交给哪个后端团队处理”,再将任务分配给最合适的 “团队成员”(后端服务器),同时监控 “成员状态”,确保任务高效执行。
三、典型应用场景
- Web 服务负载均衡
- 为 Nginx、Apache 等 Web 服务器集群分发 HTTP/HTTPS 请求,提高系统并发能力(如电商网站、门户网站)。
- 示例:通过 HAProxy 将用户请求分发到 3 台 Web 服务器,同时屏蔽故障节点,确保服务可用。
- 数据库读写分离代理
- 结合 MySQL 主从架构,将读请求转发到从库集群,写请求转发到主库,实现读写分离,减轻主库压力。
- 示例:配置 HAProxy 根据 SQL 语句类型(SELECT/INSERT),自动将读请求路由到从库,写请求路由到主库。
- API 网关
- 作为微服务架构的入口,统一接收客户端 API 请求,转发到对应的微服务实例,并实现限流、认证、日志记录等功能(轻量级场景可替代 Kong、Spring Cloud Gateway)。
- 高可用集群入口
- 与 LVS 相比,HAProxy 在七层(应用层)的灵活性更高(如基于 URL 路由),适合需要复杂规则转发的场景;而 LVS 在四层(传输层)性能更优,适合超大规模流量。实际架构中,常采用 “LVS(四层)+ HAProxy(七层)” 的组合,兼顾性能和灵活性。
四、与同类工具的对比
工具
优势
劣势
适用场景
HAProxy
支持七层代理,规则灵活;健康检查强大;轻量高效
四层性能略逊于 LVS;配置相对复杂
中小型 Web 集群、API 网关、数据库代理
Nginx
配置简单;支持静态资源缓存;适合中小规模负载
高并发下性能略逊于 HAProxy;健康检查较弱
中小型 Web 服务、静态资源服务器
LVS
四层性能极强(接近硬件负载均衡);支持大规模集群
不支持七层代理;配置复杂;依赖内核模块
超大规模 TCP 服务(如高并发游戏服务器)
五 、总结
HAProxy 是一款高性能、多功能的负载均衡器,以灵活的七层代理能力、强大的健康检查和轻量特性著称,广泛应用于 Web 服务、数据库集群、API 网关等场景。它不仅能提升系统的并发处理能力,还能通过健康检查和高可用配置保障服务稳定性,是企业级架构中不可或缺的中间件工具。
实践
环境配置 :配置三台主机,一台配置haproxy 另外两台当服务器。
网络配置haproxy:172.25.254.100 rs1:172.25.254.10 rs:172.25.254.20
关闭永久防火墙 systemctl disable --now firewalld.service
关闭永久selinux: grubby --update-kernel ALL --args=\"selinux=0\"
global配置
多进程和多线程
编辑主配置文件 vim /etc/haproxy/haproxy.cfg
nbthread 2 #启用多线程
proxies参数说明proxies
编辑基本配置
测试效果:
socat 工具
对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工 具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向 通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket文件等
haproxy的状态界面
测试页面
4.1 静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度
等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
4.1.1 static-rr:基于权重的轮询调度
不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
不支持端服务器慢启动
其后端主机数量没有限制,相当于LVS中的 wrr
Note
慢启动是指在服务器刚刚启动上不会把他所应该承担的访问压力全部给它,而是先给一部分,当没
问题后在给一部分
示例:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode http
balance static-rr
server webserver1 192.168.0.101:80 weight 2 check inter 3s fall 3 rise 5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5
...上面内容省略...
4.1.2 first
根据服务器在列表中的位置,自上而下进行调度
其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
其会忽略服务器的权重设置
不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
示例:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode http
balance 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
...上面内容省略...
测试效果:
#在两台主机上分别执行此循环,可以观察是否102被调度到
while true;do curl 172.25.254.100 ; sleep 0.1;done
4.2 动态算法
动态算法
基于后端服务器状态进行调度适当调整,
新请求将优先调度至当前负载较低的服务器
权重可以在haproxy运行时动态调整无需重启
4.2.1 roundrobin
1. 基于权重的轮询动态调度算法,
2. 支持权重的运行时调整,不同于lvs中的rr轮训模式,
3. HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),
4. 其每个后端backend中最多支持4095个real server,
5. 支持对real server权重动态调整,
6. roundrobin为默认调度算法,此算法使用广泛
示例:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode http
balance 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
...上面内容省略...
动态调整权重
[root@haproxy ~]# echo \"set weight webserver_80/webserver1 2\" | socat stdio
/var/lib/haproxy/haproxy.sock
4.2.2 leastconn
leastconn加权的最少连接的动态
支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户
端连接)
比较适合长连接的场景使用,比如:MySQL等场景。
示例:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
listen webserver_80
bind 172.25.254.100:80
mode http
balance leastconn
server webserver1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise5
server webserver2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise5
总结算法
一、基础调度算法
1. 轮询(Round Robin)
- 原理:按顺序依次将请求分发到后端服务器,循环往复。
- 配置示例:
backend web_servers
balance roundrobin
server web1 172.25.254.10:80 check
server web2 172.25.254.20:80 check
- 适用场景:后端服务器性能相近,且请求处理时间差异不大的场景(如静态资源服务器)。
- 特点:简单公平,但未考虑服务器实际负载(如某些服务器处理速度慢时可能过载)。
2. 加权轮询(Weighted Round Robin)
- 原理:根据服务器性能差异分配权重,权重高的服务器接收更多请求。
- 配置示例:
backend web_servers
balance roundrobin
server web1 172.25.254.10:80 check weight 3
server web2 172.25.254.20:80 check weight 2
- 适用场景:后端服务器硬件配置不同(如高配服务器权重设为 5,低配设为 2)。
- 特点:灵活调整负载分配,但仍未动态感知服务器实时负载。
二、动态调度算法
3. 最少连接(Least Connections)
- 原理:优先将请求分配给当前连接数最少的服务器,动态平衡负载。
- 配置示例:
plaintext
backend web_servers
balance leastconn
server web1 172.25.254.10:80 check
server web2 172.25.254.10:80 check
- 适用场景:请求处理时间差异较大的场景(如数据库查询、复杂业务逻辑)。
- 特点:避免长连接请求集中在某些服务器,但未考虑服务器性能差异(如低配服务器可能因连接数少而被过度分配)。
4. 加权最少连接(Weighted Least Connections)
- 原理:结合权重和连接数,计算 “有效连接数”(实际连接数 / 权重),优先选择有效连接数最少的服务器。
- 配置示例:
backend web_servers
balance leastconn
server web1 172.25.254.10:80 check weight 3 # 高配服务器权重高
server web2 172.25.254.20:80 check weight 1 # 低配服务器权重低
- 适用场景:服务器硬件差异明显,且请求处理时间不均的场景(如混合云环境)。
- 特点:综合考虑服务器性能和实时负载,平衡性最佳,是 HAProxy 的默认算法。
三、会话保持相关算法
5. 源地址哈希(Source IP Hash)
- 原理:基于客户端 IP 地址进行哈希计算,将同一 IP 的请求始终路由到同一服务器。
- 配置示例:
backend web_servers
balance source
server web1 172.25.254.10:80 check
server web2 172.25.254.20:80 check
- 适用场景:需要会话保持的场景(如未使用分布式会话的系统),或缓存集群(确保同一用户请求命中同一缓存服务器)。
- 特点:实现简单,但可能导致负载不均(如大量客户端来自同一网段)。
6. URI 哈希(URI Hash)
- 原理:基于请求的 URI(如 /api/users)进行哈希,相同 URI 的请求路由到同一服务器。
- 配置示例:
plaintext
backend static_servers
balance uri
server static1 172.25.254.10:80 check
server static2 172.25.254.20:80 check
- 适用场景:静态资源服务器集群(如 CDN),确保同一资源始终由同一服务器处理,提高缓存命中率。
- 特点:适合内容分发网络(CDN),但不适合动态业务(如用户会话)。
7. URL 参数哈希(URL Parameter Hash)
- 原理:基于 URL 中的特定参数(如 session_id 或 user_id)进行哈希,确保带相同参数的请求路由到同一服务器。
- 配置示例:
plaintext
backend app_servers
balance url_param user_id # 基于user_id参数哈希
server app1 172.25.254.10:8080 check
server app2 172.25.254.20:8080 check
- 适用场景:微服务架构中,需将同一用户的请求路由到同一服务实例(如用户服务)。
- 特点:更精确的会话保持,但需确保请求中包含稳定的参数。
四、其他高级算法
8. 随机(Random)
- 原理:随机选择后端服务器,可结合权重调整概率。
- 配置示例:
plaintext
backend web_servers
balance random
server web1 172.25.254.10:80 check weight 2
server web2 172.25.254.20:80 check weight 1
- 适用场景:测试环境或对负载均衡精度要求不高的场景。
- 特点:实现简单,但可能导致负载波动较大。
9. 最少响应时间(Least Time)
- 原理:结合服务器连接数和平均响应时间,选择 “响应最快且连接数最少” 的服务器。需通过 slowstart 或 httpchk 收集响应时间数据。
- 配置示例:
plaintext
backend web_servers
balance leasttime
server web1 172.25.254.10:80 check slowstart 30s # 冷启动期30秒
server web2 172.25.254.20:80 check slowstart 30s
- 适用场景:对响应时间敏感的业务(如电商支付、API 网关)。
- 特点:需足够的请求样本才能准确评估响应时间,冷启动期可避免新上线服务器被过载。
五、算法选择建议
场景
推荐算法
原因
静态资源负载均衡(如 CDN)
uri 或 url_param
确保同一资源始终由同一服务器处理,提高缓存命中率。
动态业务(如 Web 应用)
leastconn
考虑服务器实时连接数,适合处理时间不均的请求。
服务器硬件差异明显
weighted leastconn
结合权重和连接数,平衡性能差异。
需要会话保持(如未用分布式会话)
source 或 url_param
基于 IP 或参数确保同一用户请求路由到同一服务器。
对响应时间敏感的业务
leasttime
综合考虑连接数和响应时间,优先选择最快的服务器。
六、会话保持的替代方案
除了调度算法,HAProxy 还提供独立的会话保持机制(更灵活,推荐优先使用):
1. 基于 Cookie 的会话保持
plaintext
backend web_servers
balance roundrobin
cookie SERVERID insert indirect nocache # 插入Cookie
server web1 172.25.254.10:80 check cookie web1
server web2 172.25.254.20:80 check cookie web2
- 原理:HAProxy 在响应中插入 Cookie(如 SERVERID=web1),后续请求携带该 Cookie 时,强制路由到对应服务器。
2. 基于客户端 IP 的粘性会话
plaintext
backend web_servers
balance roundrobin
stick-table type ip size 200k expire 30m # 创建IP会话表
stick on src # 基于客户端IP保持会话
server web1 172.25.254.10:80 check
server web2 172.25.254.20:80 check
- 原理:通过会话表记录客户端 IP 与服务器的映射关系,实现粘性会话。
七、总结
HAProxy 的调度算法覆盖了从简单轮询到智能动态负载的多种场景,选择时需结合业务特性、服务器配置和性能需求。在实际应用中,建议优先使用 leastconn(加权最少连接)作为默认算法,对于需要会话保持的场景,可结合 Cookie 或 stick-table 机制,而非单纯依赖哈希算法。通过合理配置调度算法,可显著提升系统的负载均衡效果和整体性能。
高级功能及配置
IP透传
web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
四层IP透传
在主配置文件中
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\"\';
Server中加入listen 80 proxy_protocol; #启用此项,将无法直接访问此网站,只能通过四层代理 [::]:80;
七层IP透传
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For\"首部,其值为前端客户端的地址;用于 向后端主发送真实的客户端IP
示例
listen webserver_80
option forwardfor
bind 172.25.254.100:80
mode http
balance roundrobin
server webserver1 172.25.254.10:80 send-proxy weight 1 check inter 3s fall 3
rise 5
server webserver1 172.25.254.20:80 weight 1 check inter 3s fall 3 rise 5
在rs的nginx配置中
LogFormat \"%{X-Forwarded-For}i %a %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"% {User-Agent}i\\\"\" combined
访问控制列表ACL,Access Control Lists)
是一种基于包过滤的访问控制技术 它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过 滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内 容进行匹配并执行进一步操作,比如允许其通过或丢弃。
#用acl来定义或声明一个acl
acl [flags] [operator] []
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
acl [修饰符...]
- ACL 名称:自定义标识符,用于后续引用(如use_backend)。
- 匹配类型:指定要匹配的对象(如hdr表示 HTTP 头,path表示 URL 路径)。
- 匹配模式:定义匹配规则(如字符串、正则表达式、IP 范围等)。
- 修饰符:可选参数,用于调整匹配行为(如-i表示忽略大小写)。
二、常见匹配类型
1. HTTP 请求相关
匹配类型
描述
示例
hdr()
匹配 HTTP 请求头(如Host、User-Agent)
acl is_google hdr(User-Agent) -i googlebot
path
匹配 URL 路径(不含查询参数)
acl is_api path_beg /api
url
匹配完整 URL(含路径和查询参数)
acl has_token url_sub token=123
method
匹配 HTTP 方法(GET、POST 等)
acl is_post method POST
query
匹配查询参数(如?id=123)
acl has_id query -m str id=123
2. 客户端相关
匹配类型
描述
示例
src
匹配客户端 IP 地址
acl from_internal src 192.168.1.0/24
dst
匹配目标 IP 地址(VIP)
acl to_vip dst 10.0.0.1
ssl_fc_sni
匹配 TLS 握手时的 SNI(Server Name Indication)
acl is_https hdr(host) -i example.com
3. 时间相关
匹配类型
描述
示例
hour
匹配请求时间的小时(0-23)
acl off_peak hour ge 22 or le 6
weekday
匹配请求时间的星期(0-6,0 为周日)
acl weekend weekday 0,6
4. 状态和统计相关
匹配类型
描述
示例
sc0-sc3
匹配响应状态码范围(如sc0表示 1xx,sc1表示 2xx)
acl is_success sc1
srv_conn
匹配后端服务器当前连接数
acl server_busy srv_conn ge 1000
三、匹配模式与修饰符
1. 字符串匹配
- -m str:精确字符串匹配(默认)。
plaintext
acl is_admin hdr(X-User-Role) -m str admin # 精确匹配\"admin\"
- -m sub:子字符串匹配(包含即可)。
plaintext
acl is_image url_sub .jpg .png .gif # 匹配包含.jpg/.png/.gif的URL
- -i:忽略大小写。
plaintext
acl is_googlebot hdr(User-Agent) -i googlebot # 不区分大小写
2. 正则表达式匹配
- -m reg:使用 PCRE 正则表达式。
plaintext
acl is_mobile hdr(User-Agent) -m reg -i ^.*(mobile|android).*$
- -m beg:前缀匹配(比正则更高效)。
plaintext
acl is_api path_beg /api # 匹配以/api开头的路径
3. 数值比较
- -m int:将值视为整数进行比较(如端口、连接数)。
plaintext
acl high_port dst_port ge 10000 # 目标端口≥10000
- 比较操作符:eq(等于)、ne(不等于)、lt(小于)、le(小于等于)、gt(大于)、ge(大于等于)。
4. IP 地址匹配
- CIDR 格式:直接使用 IP 段(如192.168.1.0/24)。
plaintext
acl from_internal src 192.168.1.0/24 10.0.0.0/8 # 多个IP段用空格分隔
- -m ip:显式指定 IP 匹配(可结合反选)。
plaintext
acl not_from_internal src -m ip !192.168.1.0/24 # 非内网IP
四、ACL 组合与逻辑运算
多个 ACL 可通过逻辑运算符组合:
- &&:逻辑与(同时满足)。
- ||:逻辑或(满足其一)。
- !:逻辑非(取反)。
示例:
# 匹配来自内网且请求路径为/api的请求
acl internal_api src 192.168.1.0/24 && path_beg /api
# 匹配非移动端的GET请求
acl desktop_get !hdr(User-Agent) -i mobile && method GET
五、ACL 的应用场景
1. 基于域名转发
frontend http_front
bind *:80
mode http
acl is_www hdr(host) -i www.example.com
acl is_api hdr(host) -i api.example.com
use_backend web_servers if is_www
use_backend api_servers if is_api
2. 基于 URL 路径分流
frontend http_front
bind *:80
mode http
acl is_static path_beg /static /images
acl is_admin path_beg /admin
use_backend static_servers if is_static
use_backend admin_servers if is_admin
default_backend app_servers
3. 限制特定 IP 访问
frontend http_front
bind *:80
mode http
acl blocked_ip src -f /etc/haproxy/blocked_ips.lst # 从文件加载IP列表
http-request deny if blocked_ip # 拒绝被阻止的IP
4. 按时间段分流
frontend http_front
bind *:80
mode http
acl off_peak hour ge 22 or le 6 # 22点到次日6点为低谷期
use_backend backup_servers if off_peak # 低谷期使用备用服务器
default_backend main_servers
六、性能优化建议
- 优先使用高效匹配类型:
- 字符串前缀匹配(-m beg)比正则表达式(-m reg)更高效。
- IP 匹配(src)比字符串匹配(如解析X-Forwarded-For头)更高效。
- 避免复杂正则表达式:
复杂正则会显著降低性能,尽量使用简单的字符串匹配或前缀匹配。 - 合理组织 ACL 顺序:
将高频匹配的 ACL 放在前面,减少不必要的检查。 - 使用列表文件:
对于大量 IP 或 URL 的匹配,使用-f /path/to/file从文件加载规则,避免配置文件臃肿。
七、常见 ACL 配置错误
- 大小写敏感:
HTTP 头名称(如Host)默认大小写敏感,需用-i修饰符忽略大小写。 - 路径匹配陷阱:
path_beg /api会匹配/api、/api/v1,但不会匹配/apiv1(需用正则)。 - 查询参数处理:
path不包含查询参数(如?id=123),需用url或query匹配。 - 正则表达式转义:
特殊字符(如.、$)在正则中需转义(如\\.)。
掌握 ACL 匹配规范后,可结合 HAProxy 的use_backend、http-request、http-response等指令实现复杂的流量控制策略,如灰度发布、A/B 测试、请求过滤等高级功能。