HAPorxy简介
HAProxy(High Availability Proxy)是一款高性能、开源的负载均衡器与反向代理服务器,主要用于 TCP 和 HTTP 协议的流量分发,广泛应用于高并发、高可用的网络架构中
核心特性
超高性能与低资源消耗
基于单进程、多线程模型,处理并发连接能力极强,单实例可轻松支撑数万并发请求
灵活的负载均衡策略
支持多种算法如:轮询、加权轮询、源地址哈希、最少链接
强大的健康检查与高可用
内置多层健康检查机制(TCP 层、HTTP 层),可定期检测后端服务器状态(如端口是否存活、HTTP 响应码是否正常)
精细化的流量控制与安全防护
可设置连接限速、请求限流,防止后端服务器被流量冲击
支持 ACL(访问控制列表),基于 IP、请求方法、URL 等条件过滤恶意请求(如拦截爬虫、限制特定 IP 访问)
集成 SSL/TLS 终止功能,可在负载均衡层处理 HTTPS 加密解密,减轻后端服务器负担
HAProxy的安装和服务信息
安装软件包
dnf install haproxy -y
haproxy基本信息:
软件安装包 | 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的基本配置信息
global配置
参数说明:
log | 定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个 |
chroot | 锁定运行目录 |
pidfile | 指定pid文件 |
maxconn | 指定最大连接数 |
user | 指定haproxy的运行用户 |
group | 指定haproxy的运行组 |
daemon | 指定haproxy以守护进程方式运行 |
# turn on stats unix socket(在此处可以指定进程数量或者线程数量,多线程和多进程只可以指定一个,不可指定多个)
stats socket | 指定haproxy的套接字文件 |
nbproc | 指定haproxy的work进程数量,默认是1个 |
cpu-map 1 0 | 指定第一个work绑定第一个cpu核心 |
cpu-map 2 1 | 指定第二个work绑定第二个cpu核心 |
nbthread 2 | 指定haproxy的线程数量,默认每个进程一个线程 |
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM | 设置 HAProxy 监听套接字(即接受客户端连接的端口)的默认加密套件 |
ssl-default-server-ciphers PROFILE=SYSTEM | 设置 HAProxy 与后端服务器建立 SSL/TLS 连接时使用的加密套件 |
proxies配置
defaults | 默认配置项,针对以下的frontend、backend和listen生效 |
frontend | 前端servername,类似于Nginx的一个虚拟主机 server和LVS服务集 群 |
backend | 后端服务器组,类似于nginx的upstream和LVS中的RS服务器 |
listen | 将frontend和backend合并在一起配置 |
defaults配置
| 指定 HAProxy 处理HTTP 协议的流量 |
| 继承 global 段定义的日志配置 |
| 记录完整的 HTTP 日志 |
| 忽略 “空请求” 或 “无意义请求” 的日志 |
| 主动关闭服务器侧的连接 |
| 在请求头中插入 X-Forwarded-For (记录客户端真实 IP),但排除 127.0.0.0/8(本地回环地址) |
| 当后端服务器故障时,自动将请求重新分发到其他健康服务器 |
| 请求失败时,最多重试3 次 |
timeout http-request 10s | 客户端发送完整 HTTP 请求的超时(10 秒内未发完请求,直接断开) |
timeout queue 1m | 请求在 HAProxy 队列中等待的超时(1 分钟未分配到后端,返回 503) |
timeout connect 10s | HAProxy 与后端服务器建立连接的超时(10 秒未连接成功,判定后端故障) |
timeout client 1m | 客户端与 HAProxy 保持连接的超时(1 分钟无数据交互,断开客户端连接) |
timeout server 1m | HAProxy 与后端服务器保持连接的超时(1 分钟无数据交互,断开后端连接) |
timeout http-keep-alive 10s | HTTP Keep-Alive 连接的空闲超时(10 秒无新请求,关闭连接) |
timeout check 10s | 健康检查的超时(10 秒未收到后端响应,判定服务器故障) |
| HAProxy 对后端服务器的最大并发连接数限制 |
HAProxy算法
所有算法在主配置文件配置/etc/haproxy/haproxy.cfg
vim /etc/haproxy/haproxy.cfg ---编辑配置文件
静态算法
static-rr---基于权重的轮询调度
statick-rr 按照预先配置的顺序和权重,将客户端请求依次分配给后端服务器。当所有服务器都被分配一次后,算法会从头开始循环
配置文件
访问效果
first
first算法会按照服务器在配置文件中定义的顺序,依次检查每个服务器的状态,优先选择第一个可用的服务器,只有当服务器不可用时才会将流量分配至下一个服务器
配置文件内容:
实验效果:
动态算法
roundrobin
roundrobin是一种经典且常用的动态负载均衡算法,其核心思想是按照顺序循环的方式将请求分配到后端服务器,通过均衡分配流量来充分利用集群资源,会实时根据服务器的健康状态调整分配策略(例如自动排除故障服务器)可利用socat动态调整权重
配置文件:
实验效果:
leastconn
leastconn是一种基于后端服务器当前连接负载分配请求的动态负载均衡算法,核心思想是将新请求分配给当前活跃连接数最少的服务器,从而实现更精细化的负载均衡
支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户 端连接) 慢启动是指当一台服务器上线被检测到后 haproxy服务器会少量的分配流量慢慢增大
配置文件:
实验效果:
其他算法
source
source是一种通过客户端源 IP 地址实现会话保持的经典策略。其核心逻辑是:对客户端的源 IP 地址进行哈希计算,将结果映射到后端服务器集群中的某台服务器,从而确保来自同一源 IP 的请求始终被转发到同一台后端服务器
配置文件:
实验效果:
map-base 取模法
先对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请 求转发至对应的后端服务器,如:有三台后端服务器(索引分别0、1、2)若客户的ip地址哈希值为5,则5%3=2 分配到索引为2的服务器 此方法是静态的不支持动态调整权重且当有一台服务器下线时会导致多台客户主机被调度的服务器发生改变,会导致会话丢失
一致性hash
一致性哈希算法可以解决map-base取模法的多个会话丢失的问题能够确保当后端服务器数量发生变化时,只有少量请求会被重新路由,从而提高系统稳定性,其原理是将后端服务器的ip取模制成一个哈希环,再将客户端的ip取模落在后端服务器哈希环上,客户端在哈希环上经过逆时针找最近的后端服务器,这样即使有服务器上线或者下线了也只会有少量的会话丢失
一致性哈希问题:当服务器过少时会导致服务器分布不理想,可通过虚拟节点使其分布均匀
uri
path
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后 根据最终结果将请求转发到后端指定服务器 对/path;params进行哈希 相同的uri访问同一台后端服务器
配置文件:
后端服务器需要有对应文件进行测试测试结果:
url_param
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器 总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器
配置文件
测试结果
hdr取模法
基于请求头(HTTP header,通过hdr
指令获取 )中的特定信息进行哈希取模运算,从而决定将请求转发到哪一台后端服务器
配置文件:
测试效果:
HAProxy的高级功能及配置
基于cookie值的会话保持
基于 Cookie 值的会话保持(也称为 "粘性会话")是一种常用的负载均衡策略,确保来自同一客户端的请求始终被路由到同一后端服务器,从而维护会话状态的一致性。这种机制特别适用于不支持分布式会话的应用程序
配置文件:
测试结果:
HAProxy状态页
通过web界面,显示当前HAProxy的运行状态
状态页配置参数:
stats enable | 基于默认的参数启用stats page |
stats hide-version | 将状态页中haproxy版本隐藏 |
stats refresh | 设定自动刷新时间间隔,默认不自动刷新 |
stats uri | 自定义stats page uri,默认值:/haproxy?stats |
stats auth | 认证时的账号和密码,可定义多个用户,每行指定一个用户 |
状态页配置文件:
状态页内容
状态页参数
session rate(每秒的连接会话信息):
cur:每秒的当前会话数量 :
max:每秒新的最大会话数量
limit:每秒新的会话限制量
sessions(会话信息):
cur:当前会话量
max:最大会话量
limit: 限制会话量
Total:总共会话量
LBTot:选中一台服务器所用的总时间
Last:和服务器的持续连接时间
Wght:权重
Bytes(流量统计):
In:网络的字节输入总量
Out:网络的字节输出总量
Dwn:后端服务器连接后都是DOWN的数量
Denied(拒绝统计信息):
Req:拒绝请求量
Resp:拒绝回复量
Errors(错误统计信息):
Req:错误请求量
conn:错误链接量
Resp:错误响应量
Warnings(警告统计信息):
Retr:重新尝试次数
Redis:再次发送次数
Server(real server信息):
Status:后端机的状态,包括UP和DOWN
LastChk:持续检查后端服务器的时间
Act:活动链接数量
Bck:备份的服务器数量
Chk:心跳检测时间
Dwntme:总的downtime时间
Thrtle:server 状态
IP透传
四层IP透传
hapeoxy配置文件:
后端服务器nginx配置文件
实验效果:
访问后查看日志
七层IP透传使用http默认是开启的
ACL
访问控制列表ACL,是一种基于包过滤的访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配)即对接收到的报文进行匹配和过 滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作
ACL匹配规范
hdr_beg(<name>[, <occ>]) ---匹配请求头中指定字段值的开头部分
hdr_end(<name>[, <occ>]) ---匹配请求头中指定字段值的结尾部分
hdr_dom(<name>[, <occ>]) ---域名部分匹配(带子域名),主要用于 host
hdr_dir(<name>[, <occ>]) ---路径匹配(针对 URI)
hdr_len(<name>[, <occ>]) ---匹配请求头字段值的长度
hdr_reg(<name>[, <occ>]) ---正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub(<name>[, <occ>]) ---子串匹配,即字段值中包含某个子字符串即可
ACL匹配规则
-i | 不区分大小写 |
-m | 使用指定的正则表达式匹配方法 |
-n | 不做DNS解析 |
-u | 禁止acl重名,否则多个同名ACL匹配或关系 |
ACL操作符
整数比较
eq(等于) ge(大于等于) gt(大于) le(小于等于) lt(小于)
字符比较
exact match | 完全一致才匹配 |
substring match | 包含子串就匹配 |
suffix match | 结尾一致才匹配 |
prefix match | 开头一致才匹配 |
subdir match | 按 / 分割,任意段匹配 |
domain match | 按 . 分割,任意段匹配 |
ACL示例实验
基于域名匹配
haproxy配置文件:
实验效果
基于源IP或子网调度访问
haproxy配置文件:
实验效果:
基于源地址的访问控制
haproxy配置文件:
实验效果:
基于浏览器类型
实验效果
HAProxy四层负载
针对除HTTP以外的TCP协议应用服务访问的应用场景
对MySQL四层负载示例:
在后端服务器下载mariadb-server
编辑配置文件(修改数据库id为了观察实验效果)
haproxy配置文件:
实验结果:
自定义错误页面
可以指定错误时跳转页面
配置文件内容:
错误页面文件内容将后端服务器关闭模拟错误
实验效果: