一、概念
HAProxy(H igh A vailability P roxy)是一款开源的高性能 TCP/HTTP 负载均衡器 和 反向代理 软件,被广泛应用于构建高可用、高并发的现代网络架构。
核心功能:
-
负载均衡(Load Balancing)
-
支持四层(TCP)和七层(HTTP/HTTPS)流量分发。
-
提供多种调度算法:轮询(
roundrobin
)、最少连接(leastconn
)、源IP哈希(source
)等。
-
-
反向代理(Reverse Proxy)
-
隐藏后端服务器细节,对外提供统一入口。
-
支持 SSL 终端(SSL Termination),卸载后端服务器加密负担。
-
-
高可用(High Availability)
- 结合 Keepalived 实现双机热备(VRRP 协议)。
-
流量治理
- 请求过滤、速率限制、连接控制等。
多层级负载均衡
层级 | 协议支持 | 典型场景 |
---|---|---|
四层(L4) | TCP/UDP | 数据库集群、Redis、SSH 跳板 |
七层(L7) | HTTP/HTTPS/HTTP2/3 | Web 应用、API 网关、微服务路由 |
与 Nginx/LVS 对比
特性 | HAProxy | Nginx | LVS |
---|---|---|---|
协议支持 | ★★★ (TCP/HTTP/SSL) | ★★★ (HTTP/SSL) | ★★ (TCP/UDP) |
七层能力 | ★★★ (ACL/重写/缓存) | ★★★ | ✘ (仅四层) |
性能 | ★★★ (L4/L7 均优) | ★★ (HTTP 强) | ★★★ (L4 极致) |
配置灵活性 | ★★★ (DSL 语法) | ★★ (类 C 配置) | ★ (ipvsadm 命令行) |
健康检查 | ★★★ (多协议支持) | ★★ | ★ (基础 TCP 检查) |
二、实验
1、实验环境的搭建
准备3台主机:
主机1
主机名:haproxy
ip:172.25.254.100
主机2
主机名:hp-RS1
ip:172.25.254.10
主机3
主机名:hp-RS2
ip:172.25.254.20
(1)软件包安装
两台RS都安装nginx:


设置开机自启动(两个都设置)

(2)关闭火墙
两台RS关闭火墙:


(3)两台RS设置nginx的index.html内容
设置这个是方便后续测试


(4)连通测试
haproxy主机curl一下两台RS

连接成功
实验环境搭建完毕
(5)方便码字的tab键设置


2、haproxy的安装和frontend区
(1)安装haproxy
dnf安装

启动服务

(2)进入haproxy配置文件

进入编写

wq
重启服务

3、global配置(多进程与多线程)
(1)global配置参数解释
配置区域在/etc/haproxy/haproxy.conf的global区

参数 | 说明 | 示例 | 必要性 |
---|---|---|---|
daemon |
以守护进程(后台)模式运行 | daemon |
✅ 生产必选 |
user group |
指定运行用户/用户组(降权运行) | user haproxy group haproxy |
✅ 安全必选 |
chroot |
切换根目录(增强安全性) | chroot /var/lib/haproxy |
⚠️ 可选 |
nbproc |
工作进程数(CPU 核数绑定) | nbproc 4 |
⚠️ 高并发必选 |
nbthread |
每进程线程数(需启用线程) | nbthread 2 |
⚠️ 现代 CPU 优化 |
stats socket |
管理套接字路径(动态调整配置) | stats socket /run/haproxy/admin.sock |
⚠️ 运维必选 |
(2)多进程与多线程
1)多进程(nbproc)
开启多进程则进入haproxy的配置文件


wq
解释:
- nbproc 2 ------ 启用多进程,2个进程
- cpu-map 1 0 ------ 进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗,1表示指定第一个work绑定第一个核心,0表示第一个核心,核心从0开始算(类似数组下标)
- cpu-map 2 1 ------ 指定第二个work绑定第二个cpu核心
重启服务
查看多进程信息

2)多线程(nbthread)
开启多线程也是进入haproxy的配置文件


wq
解释:
nbthread ------ 启动多线程,线程数为2
多线程和多进程只能存在一个,另一个要#号引掉
查看多线程
[root@haproxy ~]# cat /proc/1653/status

数字1653是刚刚查看的进程id
未开启前,thread为1

而修改完,重启服务后

重启服务后,要先pstree才有进程id哦

thread变为2

这就是多线程
4、socat工具
socat
是 HAProxy 生态中不可替代的底层诊断工具 ,它通过直接访问 HAProxy 的 Unix 管理套接字实现高级运维操作。
为什么需要 socat
?
场景 | 传统方案痛点 | socat 解决方案 |
---|---|---|
动态服务器状态调整 | 需重载配置(中断连接) | 实时启用/禁用服务器(零中断) |
紧急故障屏蔽 | 修改配置+重载耗时 >30s | 1秒内下线故障节点 |
内存泄漏分析 | 依赖外部监控工具 | 直接dump进程内存结构 |
流诊断 | 抓包分析复杂 | 实时镜像指定流量 |
(1)安装
dnf安装socat


(2)修改配置文件
进入haproxy配置文件:

进入编辑:
(3)常用示例
1)查看haproxy状态
echo "show info" | socat stdio /var/lib/haproxy/stats

2) 查看集群状态
echo "show servers state" | socat stdio /var/lib/haproxy/stats

3)查看集群权重
echo get weight webcluster/web1 | socat stdio
echo get weight webcluster/web2 | socat stdio

4)设置权重
echo "set weight webcluster/web1 1 " | socat stdio /var/lib/haproxy/stats

可以查看一下设置成功没:

成功
5)下线后端服务器
echo "disable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats

6)上线后端服务器
echo "enable server webcluster/web1 " | socat stdio /var/lib/haproxy/stats

5、haproxy算法
(1)static-rr
-
原理: 也是轮询算法,但不支持运行时权重动态调整。
-
权重支持: 支持 ,但权重在启动时确定后,在运行时无法通过运行时 API 动态修改(而
roundrobin
可以)。 -
特点: 比
roundrobin
稍简单一些,开销略低。如果确定不需要在运行时动态调整权重,可以使用此算法。



static-rr不支持热更新:

测试
(2)first
-
原理: 按照服务器在配置文件中声明的顺序进行分配。将请求分配给列表中第一个可用的服务器。仅当第一个服务器达到其最大连接数 (
maxconn
) 时,才会分配给下一个可用的服务器。 一旦某个服务器连接数降到maxconn
以下,新请求又会优先分配给它。 -
权重支持: 不支持。
-
特点: 尽量将流量集中到列表前面的服务器,直到它们满载。可能导致负载分布非常不均衡,前面的服务器压力很大,后面的服务器很空闲。



测试

都是RS1,因为要等RS1满了,才会轮到到RS2
(3)roundrobin
-
原理: 最常用、最经典的轮询算法。按顺序依次将新请求分配给后端服务器列表中的下一个服务器。循环往复。
-
权重支持: 支持 。服务器可以配置权重 (
weight
)。权重高的服务器在轮询周期内会获得更多比例的请求。 -
特点: 简单、公平、可预测。在服务器性能相近且请求处理时间相对均匀时效果很好。



测试

标准的轮询
(4)leastconn
-
原理: 最少连接数算法。 将新请求分配给当前活跃连接数最少的后端服务器。
-
权重支持: 支持 。计算时会考虑权重。实际比较的是
(当前连接数) / (权重)
。值最小的服务器胜出。权重高的服务器能承受更多连接。 -
特点: 非常适合处理时间差异很大的请求(例如数据库连接、长连接应用如 WebSocket、消息队列)。能更公平地根据服务器实际处理能力分配负载。



测试
和轮询差不多

(5)source
-
原理: 源 IP 地址哈希。 使用客户端的源 IP 地址计算哈希值,决定分配到哪个后端服务器。
-
权重支持: 不支持。哈希结果直接映射到服务器,权重不影响哈希分配本身(但影响服务器池的组成)。
-
特点: 确保来自同一个客户端的请求总是落到同一台服务器(只要服务器池不变)。简单但不够灵活,如果客户端使用代理或 NAT,大量不同用户可能共享同一个源 IP,导致负载不均衡。



测试

(6)uri
-
原理: 整个 URI 哈希。 使用 HTTP 请求的完整 URI(包括路径和查询参数,例如
/path/page?param=value
)计算哈希值。 -
权重支持: 不支持。
-
特点: 将访问相同 URI 的请求固定到同一服务器。有助于利用服务器本地的缓存(如果缓存是基于 URI 的)。



测试

(7)url-param
-
原理: URL 参数值哈希。 使用 HTTP 请求 URL 中指定的查询字符串参数的值计算哈希值。需要配置参数名(例如
url_param userid
)。 -
权重支持: 不支持。
-
特点: 非常灵活,可以根据业务关键参数(如用户 ID
userid=123
、会话 IDsessionid=abc
)进行会话保持。



测试


(8)hdr
-
原理: HTTP 头哈希。 使用指定的 HTTP 请求头的值计算哈希值。需要配置头名称(例如
hdr(Cookie)
,hdr(Host)
)。 -
权重支持: 不支持。
-
特点: 极其灵活,可以利用任何 HTTP 头信息做会话保持,最常用的是
Cookie
头。



测试

模拟不同的浏览器访问时:
浏览器browser1访问,RS1接待


浏览器browser2访问,就变成RS2接待了


6、cookie
(1)概念
HAProxy 中的 cookie
指令是实现 会话保持(Session Persistence)或粘性会话(Sticky Session) 最常用、最强大且推荐的方式之一。它通过在客户端的浏览器中设置或利用一个特定的 Cookie,确保来自同一用户的后续请求能被 HAProxy 正确地路由到最初处理其请求的同一台后端服务器。
-
目的: 解决有状态应用(Stateful Application)的问题。例如,用户的购物车数据、登录会话信息等通常存储在特定后端服务器的内存或本地缓存中。如果用户的后续请求被负载均衡到不同的服务器,这些状态信息将丢失,导致应用出错。
-
原理:
-
HAProxy 在将第一个响应返回给客户端时(或者在某些模式下处理第一个请求时),会插入(Insert) 或改写(Rewrite) 一个特殊的 HTTP
Set-Cookie
响应头。 -
这个 Cookie 的值通常直接包含 或间接映射到 处理该请求的后端服务器的标识符(通常是
server
块中定义的cookie
值或内部 ID)。 -
客户端浏览器收到这个 Cookie 后会存储它,并在后续向同一域名发送请求时,自动在
Cookie
请求头中携带它。 -
HAProxy 接收到后续请求时,会解析 该 Cookie 的值,提取出服务器标识符,并直接将请求转发到对应的服务器,绕过负载均衡算法。
-
(2)实验举例



测试
-b 指定cookie值

可以看到访问cookie值为servera时,被调度到RS1处理; cookie值为serverb时,被调度到RS2处理
与我们在haproxy配置文件里配置的一致
7、HAProxy状态页
HAProxy 的状态页(Stats Page) 是实时监控负载均衡集群的核心工具,通过 Web 页面展示关键性能指标和后端节点状态。
(1)各种参数解析
基础配置项解析
参数 | 说明 | 示例 |
---|---|---|
stats enable |
启用状态页(无此选项则不生效) | stats enable |
stats uri |
状态页访问路径 | stats uri /admin?stats |
stats auth |
基础认证(明文用户/密码) | stats auth admin:SecurePass123 |
stats refresh |
页面自动刷新间隔(秒) | stats refresh 5s |
stats bind |
监听地址和端口(默认同 frontend) | stats bind :1936 |
进阶安全控制
参数 | 说明 | 生产环境示例 |
---|---|---|
stats hide-version |
隐藏 HAProxy 版本号(防漏洞扫描) | stats hide-version |
stats admin |
动态启用管理功能(条件触发) | stats admin if { src 10.0.0.0/24 } |
stats http-request |
集成 ACL 复杂控制 | stats http-request allow if { src -f /etc/haproxy/allowlist } |
stats realm |
认证对话框提示文本 | stats realm "HAProxy Protected" |
(2)实验


解释:
- listen haproxystatus ------ 定义名为 "haproxystatus" 的监听块
- mode http ------ 使用 HTTP 模式(七层代理)
- bind *:9999 ------ 绑定所有网络接口的 9999 端口
- stats enable ------ 启用状态统计页面
- log global ------ 使用全局日志配置
- stats uri /status ------ 设置状态页的访问路径为 /status
- stats auth lincoln:lincoln ------ 设置访问认证的用户名/密码

重启服务时如果报错:

可能是SELinux的原因,把其关闭:

再试一次应该就没报错了
测试
浏览器访问刚刚写的端口号9999,后面加/status
http://172.25.254.100:9999/status

出现输入用户名和密码,输入刚刚设定的,这里我设定的是自己的名字:

登录成功后,访问到页面:

8、IP透传
HAProxy 的 IP 透传 是指将原始客户端的真实 IP 地址传递给后端服务器,而不是让后端服务器只看到 HAProxy 自身的 IP 地址。这对于后端应用至关重要,因为它需要知道真实的客户端信息来进行日志记录、访问控制、地理定位、速率限制、安全审计等操作。
HAProxy 本身作为反向代理或负载均衡器,是客户端与后端服务器之间的中间节点。默认情况下,后端服务器看到的 TCP 连接源 IP 地址就是 HAProxy 的 IP 地址。
(1)7层ip透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
进入haproxy配置文件
开启Listen就把frontend和backend关了
(2)4层ip透传
1)未开启时
未开启4层ip透传时的各种配置:
haproxy.cfg



nginx.conf(两台RS)



未开启4层ip透传时的访问测试极其日志:
访问测试

日志查看
在一台RS上查看nginx日志会发现,其真实访问源地址是看不到的(红框为-)

2)开启时
开启4层ip透传时的各种配置:
nginx.conf(两台RS)



haproxy.cfg


开启4层ip透传时的访问测试极其日志:
访问测试

查看日志nginx

这样就看到源ip地址了
9、ACL
HAProxy 的 ACL 是其核心功能之一,用于定义复杂的流量匹配规则,实现基于请求内容(如 URL、Header、IP、路径等)的智能路由、过滤或决策。
(1)Client里做解析
先在Client里做域名解析,不然后续测试访问不了
解析在/etc/hosts做


这样就有解析了
(2)基本配置
开启frontend、backend

其余的Listen引掉

(3)ACL配置选项
1)基本语法
acl <acl_name> <匹配条件类型> <匹配参数> [标志]
解释:
- acl名称(ACL-Name) ------ 可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写
- 匹配条件类型(ACL-criterion)------ 下面另外列表解释
- 匹配参数 ------ 匹配的具体值(如
/api
,User-Agent
,192.168.1.0/24
)- 标志 ------ 可选修饰符(如
-i
忽略大小写,-m
匹配模式)
2)常用匹配条件类型(ACL-criterion)详解:
路径匹配 (URL Path)
条件类型 | 说明 | 示例 |
---|---|---|
path |
精确匹配路径 | acl exact_path path /login |
path_beg |
路径开头匹配 | acl is_api path_beg /api |
path_end |
路径结尾匹配 | acl is_jpg path_end .jpg |
path_sub |
路径包含子串 | acl has_id path_sub /user/ |
path_dir |
包含目录匹配 | acl in_images path_dir /images/ |
path_reg |
正则表达式匹配 | acl uuid_path path_reg ^/user/[0-9a-f]{8}- |
path_len |
路径长度比较 | acl long_path path_len gt 100 |
域名/主机头匹配 (Host)
条件类型 | 说明 | 示例 |
---|---|---|
hdr(host) |
精确匹配 Host 头 | acl main_site hdr(host) www.example.com |
hdr_reg(host) |
正则匹配 Host | acl subsite hdr_reg(host) ^app..example.com$ |
dom |
同 hdr(host) (旧式写法) | acl legacy dom legacy.example.com |
IP地址匹配
条件类型 | 说明 | 示例 |
---|---|---|
src |
源IP匹配 | acl lan src 192.168.1.0/24 |
src_port |
源端口匹配 | acl high_port src_port gt 1024 |
dst |
目标IP匹配 | acl vip dst 10.0.0.100 |
dst_port |
目标端口匹配 | acl https_port dst_port 443 |
HTTP头部匹配
语法 | 说明 | 示例 |
---|---|---|
hdr(<name>) |
检查头部存在/值 | acl has_token hdr(X-Auth-Token) -m found |
hdr_reg(<name>) |
正则匹配头部值 | `acl is_bot hdr_reg(User-Agent) (bot |
hdr_sub(<name>) |
头部包含子串 | acl is_curl hdr_sub(User-Agent) curl |
hdr_beg(<name>) |
头部开头匹配 | acl is_moz hdr_beg(User-Agent) Mozilla |
hdr_cnt(<name>) |
头部数量检查 | acl many_cookies hdr_cnt(Cookie) gt 5 |
HTTP方法/版本
条件类型 | 说明 | 示例 |
---|---|---|
method |
HTTP方法匹配 | acl is_post method POST |
method_len |
方法长度比较 | acl long_method method_len gt 5 |
ver |
HTTP版本 | acl http2 ver 2 |
3)标志项详解
标志 | 说明 | 示例 |
---|---|---|
-i |
忽略大小写 | hdr(host) -i EXAMPLE.COM |
-m |
匹配模式 | -m str :字符串匹配 -m beg :开头匹配 -m end :结尾匹配 -m sub :子串匹配 -m reg :正则匹配 -m found :存在即匹配 |
-f |
从文件加载 | src -f /path/to/ip.list |
-n |
数值比较 | path_len -n gt 100 |
(4)ACL配置选项的实验(举一个例子)
1)添加基础acl规则和hdr_dom(host)


解释:
- hdr_dom(host) ------ 精确匹配 Host 头
- -i ------ 忽略大小写
- www.lincoln.org ------ hdr_dom(host)所匹配的域名
- if test ------ 条件语句,即匹配test这个acl规则
测试

可以看到,设置了acl规则后,我们访问www.lincoln.org就会到RS1主机,这就是acl规则
(5)实验**------**域名匹配
进入haproxy的配置文件



测试结果:
[root@Client ~]# curl www.lincoln.org
RS1 - 172.25.254.10
[root@Client ~]# curl www.lincoln.org
RS2 - 172.25.254.20
10、自定义错误页面
(1)概念
在 HAProxy 中,自定义报错页面 是一项关键功能,它允许你替换 HAProxy 生成的默认错误响应(通常是简短、技术性的纯文本或 JSON),为用户或客户端提供更友好、更专业、更具品牌特色或包含更多指导信息的 HTML 错误页面。
(2)实验


写了Listen的话frontend和backend就要记得关闭!
建立自定义报错文件



测试
关闭两个RS的nginx,模拟服务断开


然后浏览器访问ip,就能看到自定义报错界面了

11、HAProxy****四层负载
HAProxy 是一个高性能、高可用性 的负载均衡器和反向代理软件。它的四层负载均衡模式,通常称为 TCP 模式 或 Layer 4 (L4) 模式 ,专注于在传输层(TCP) 工作。这意味着 HAProxy 在此模式下不解析应用层协议(如 HTTP)的内容,它只处理 TCP 连接本身。
**(1)实验------**对 MySQL 服务实现四层负载
两台RS安装mariadb-server







Client安装mariadb(注意不是mariadb-server)

测试


12、证书
(1)证书制作
所有主机都关闭SELinux(命令setenforce 0)


解释:
openssl req
- 这是 OpenSSL 的子命令,用于处理证书签名请求 。虽然名字叫
req
,但结合-x509
选项时,它可以直接生成自签名证书,而无需先生成 CSR。
-newkey rsa:2048
-newkey
:指示 OpenSSL 生成一个新的私钥。
rsa:2048
:指定新私钥的算法为 RSA ,密钥长度为 2048 位。这是目前广泛使用的安全标准。
-nodes
这个选项的意思是 "不要用密码加密私钥"。
如果省略
-nodes
,OpenSSL 会在生成私钥时提示你设置一个密码。每次 HAProxy(或其他服务)启动使用这个私钥时,都需要输入密码,这对于自动启动的服务非常不便。重要提示: 使用
-nodes
意味着私钥文件 (lincoln.org.key
) 是未加密 存储在磁盘上的。必须严格限制该文件的访问权限(通常设置为600
或400
,仅限 root 或特定服务用户读取),否则存在安全风险。
-sha256
指定生成证书请求(以及最终证书)时使用的哈希算法 为 SHA-256。
这是当前推荐的安全哈希算法,替代了较弱的 SHA-1 或 MD5。
-keyout /etc/haproxy/certs/
lincoln
.org.key
-keyout
:指定新生成的私钥应保存到的文件路径和名称。这里私钥将被保存到
/etc/haproxy/certs/lincoln.org.key
。确保/etc/haproxy/certs/
目录存在,或者你有权限创建它。
-x509
这是命令的核心选项,改变了
openssl req
的默认行为。通常
req
用于生成证书签名请求,需要提交给证书颁发机构 (CA) 签名。
-x509
选项告诉 OpenSSL 直接生成一个自签名的 X.509 证书,而不是生成 CSR。该证书将使用刚刚生成的私钥进行签名。
-days 365
指定生成的自签名证书的有效期,单位为天。
这里设置为 365 天 (1 年)。你可以根据需要调整这个值(例如
-days 730
表示 2 年)。
-out /etc/haproxy/certs/
lincoln
.org.crt
-out
:指定生成的自签名证书应保存到的文件路径和名称。这里证书将被保存到
/etc/haproxy/certs/lincoln.org.crt
。
按照提示来输入名字那些
之后将key和crt一起放到.pem里

这样证书就生成完毕了
进haproxy配置文件配置



(2)测试访问


结束