【Linux-云原生-笔记】Haproxy相关
一、概念
HAProxy(High Availability Proxy)是一款开源的高性能 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 stdioecho 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|crawl) |
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)测试访问
结束