HAProxy 介绍
一、本质定位
HAProxy(High Availability Proxy)是一款开源的高性能 TCP/HTTP 负载均衡器和反向代理软件,由法国开发者 Willy Tarreau 于 2000 年用 C 语言开发。其名称直译为"高可用代理",精准体现了核心设计目标:通过智能流量分发构建高可用服务架构。
二、核心特性
特性 | 说明 |
---|---|
高性能 | 单实例支持数万级并发连接,可处理数十万请求/秒 |
多协议支持 | 完整支持四层(TCP/UDP)和七层(HTTP/HTTPS)负载均衡 |
会话保持 | 提供基于 Cookie/Source IP/URI 等维度的会话黏性解决方案 |
健康检查 | 主动式后端服务器监控(TCP/HTTP检查),支持优雅下线 |
动态调整 | 运行时通过 Socket API 动态修改服务器权重/状态(无需重启) |
高可用 | 支持故障自动转移(Failover)和备份服务器机制 |
三、核心架构优势
分层处理能力:
- 四层模式:基于 IP+端口快速转发,性能损耗低于 1%
- 七层模式:深度解析 HTTP 协议,支持 URL 重写、Header 修改等高级功能
智能流量分发:
支持 10+ 种负载算法,包括:
- 轮询(roundrobin)
- 最少连接(leastconn)
- 源地址哈希(source)
- URI 一致性哈希(uri)
企业级可靠性:
- 99.999% 高可用保障(通过 VRRP/Keepalived 实现)
- 热更新配置(
-sf
指令无缝重载) - 多进程绑定 CPU 核心(避免上下文切换损耗)
四、生态定位
维度 | HAProxy | Nginx | LVS |
---|---|---|---|
协议支持 | TCP/HTTP/HTTPS | HTTP/HTTPS | TCP/UDP |
会话保持 | 多维度精准控制 | 基础支持 | 仅IP哈希 |
配置灵活性 | 动态运行时调整 | 需重载配置 | 需ipvsadm命令 |
性能损耗 | 四层<1%,七层~5% | 七层~10% | <0.1% |
最佳场景 | 企业级七层负载 | Web服务器/缓存 | 亿级流量四层分发 |
总结:HAProxy 是构建现代云原生架构的流量管理中枢,特别适合需要精细流量控制、会话保持和高可用保障的企业级应用场景。其专业级的七层处理能力和运行时动态调整特性,使其成为微服务网关、API 网关和云负载均衡器的理想技术选型。
一、负载均衡核心价值
核心优势:
- 动态扩展:Web服务器水平扩展对用户无感知
- 突破瓶颈:提升业务并发处理能力
- 成本优化:节约公网IP,降低IT支出
- 安全加固:隐藏真实服务器IP
- 配置简单:固定格式配置文件
- 功能丰富:支持四层/七层代理,动态下线主机
典型应用场景:
- 解决单服务器性能瓶颈
- 提高业务系统高可用性
- 构建安全防护体系(隐藏内网结构)
- 实现业务无缝扩容
二、负载均衡类型对比
分类维度 | 四层负载均衡 | 七层负载均衡 |
---|---|---|
工作层级 | 传输层(TCP/UDP) | 应用层(HTTP/HTTPS) |
转发依据 | IP+端口 | URL/Header/Cookie等应用层信息 |
处理速度 | 更快(不解析报文内容) | 较慢(需解析应用层内容) |
功能类比 | 类似路由器 | 类似代理服务器 |
安全性 | 无法识别DDoS攻击 | 可防御SYN Flood等应用层攻击 |
代表方案 | LVS、HAProxy模拟四层 | Nginx、HAProxy七层代理 |
连接方式 | 客户端→LB→服务器(单TCP连接) | 客户端→LB + LB→服务器(双TCP连接) |
三、负载均衡技术选型
硬件方案:
产品 厂商 官网 F5 BIG-IP 美国F5网络公司 https://f5.com/zh Netscaler 美国思杰公司 https://www.citrix.com.cn Array 华耀 https://www.arraynetworks.com.cn AD-1000 深信服 http://www.sangfor.com.cn 软件方案对比:
- 四层代表:
- LVS:内核级负载,高性能
- Nginx:轻量级,支持四层代理
- HAProxy:专业级TCP负载
- 七层代表:
- Nginx:基于HTTP协议
- HAProxy:专业七层代理,支持会话保持/路径转移
- 四层代表:
四、HAProxy核心优势
- 基本特性:
- 开发语言:C语言开发
- 并发能力:支持万级并发连接
- 协议支持:TCP/HTTP负载均衡
- 关键功能:基于Cookie持久化、自动故障切换、正则表达式支持
实验环境的搭建
主机名:haproxy
ip:172.25.254.100
主机名:RS1
ip:172.25.254.10
主机名:RS2
ip:172.25.254.20
软件安装
两台RS都安装nginx:
关闭防火墙
两台RS设置nginx的index.html内容
haproxy主机curl一下两台RS
haproxy的安装
启动服务
进入haproxy配置文件
重启服务
global配置(多进程与多线程)
配置参数说明
global
log 127.0.0.1 local2 #定义全局的syslog服务器;日志服务器需要开启udp协议,最多可以定义两个
chroot /var/lib/haproxy #锁定运行目录
pidfile /var/run/haproxy.pid #指定pid文件
maxconn 100000 #指定最大连接数
user haproxy #指定haproxy的运行用户
group haproxy #指定haproxy的运行组
daemon #指定haproxy以守护进程方式运行
# turn on stats unix socket
stats socket /var/lib/haproxy/stats #指定haproxy的套接字文件
nbproc 2 #指定haproxy的工作进程数量,默认是1个
cpu-map 1 0 #指定第一个work绑定第一个cpu核心
cpu-map 2 1 #指定第二个work绑定第二个cpu核心
nbthread 2 #指定haproxy的线程数量,默认每个进程一个线程,此参数与nbproc互斥
maxsslconn 100000 #每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate 100 #指定每个客户端每秒建立连接的最大数量
多进程与多线程
重启服务
查看多进程信息
多线程(nbthread)
多进程和多线程互斥只能存在一个
socat工具
socat 是 HAProxy 生态中不可替代的底层诊断工具,它通过直接访问 HAProxy 的 Unix 管理套接字实现高级运维操作
安装
修改配置文件
常用示例
查看haproxy状态
查看集群状态
查看集群权重
haproxy算法
静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度
等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
static-rr:基于权重的轮询调度
- 不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
- 不支持端服务器慢启动
- 其后端主机数量没有限制,相当于LVS中的 wrr
first - 根据服务器在列表中的位置,自上而下进行调度
- 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
- 其会忽略服务器的权重设置
- 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
都是RS1,因为要等RS1满了,才会轮到到RS2
动态算法
动态算法
基于后端服务器状态进行调度适当调整,
新请求将优先调度至当前负载较低的服务器
权重可以在haproxy运行时动态调整无需重启
roundrobin - 基于权重的轮询动态调度算法,
- 支持权重的运行时调整,不同于lvs中的rr轮训模式,
- HAProxy中的roundrobin支持慢启动(新加的服务器会逐渐增加转发数),
- 其每个后端backend中最多支持4095个real server,
- 支持对real server权重动态调整,
- roundrobin为默认调度算法,此算法使用广泛
leastconn - leastconn加权的最少连接的动态
- 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户 端连接)
- 比较适合长连接的场景使用,比如:MySQL等场景。
其他算法
其它算法即可作为静态算法,又可以通过选项成为动态算法
source
源地址hash,基于用户源地址hash并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type支持的选项更改这个算法一般是在不插入Cookie的TCP模式下使用,也可给拒绝会话cookie的客户提供最好的会话粘性,适用于session会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash
uri
基于对用户请求的URI的左半部分或整个uri做hash,再将hash结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器
适用于后端是缓存服务器场景默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性hash
url_param
url_param对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用与电商
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server如果无没key,将按roundrobin算法
hdr
针对用户每个http头部(header)请求中的指定信息做hash,此处由 name 指定的http首部将会被取出并做hash计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
模拟不同的浏览器访问时:
浏览器browser1访问,RS1接待
浏览器browser2访问,就变成RS2接待了
高级功能及配置
介绍HAProxy高级配置及实用案例
#缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯
#可以实现session保持
#基于客户端请求报文头部做下一步处理
基于cookie的会话保持
cookie value:为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
-b 指定cookie值
可以看到访问cookie值为servera时,被调度到RS1处理; cookie值为serverb时,被调度到RS2处理与我们在haproxy配置文件里配置的一致
HAProxy状态页
HAProxy 的状态页(Stats Page) 是实时监控负载均衡集群的核心工具,通过 Web 页面展示关键性能指标和后端节点状态。
stats enable
stats hide-version
stats refresh <delay>
stats uri <prefix>
#基于默认的参数启用stats page
#将状态页中haproxy版本隐藏
#设定自动刷新时间间隔,默认不自动刷新
#自定义stats page uri,默认值:/haproxy?stats
stats auth <user>:<passwd> #认证时的账号和密码,可定义多个用户,每行指定一个用户
#默认:no authentication
stats admin { if | unless } <cond> #启用stats page中的管理功能
实验
listen haproxystatus —— 定义名为 "haproxystatus" 的监听块
mode http —— 使用 HTTP 模式(七层代理)
bind *:9999 —— 绑定所有网络接口的 9999 端口
stats enable —— 启用状态统计页面
log global —— 使用全局日志配置
stats uri /status —— 设置状态页的访问路径为 /status
stats auth yueyuxuan:yueyuxuan —— 设置访问认证的用户名/密码
IP透传
web服务器中需要记录客户端的真实IP地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
7层ip透传
当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器
4层ip透传
nginx.conf(两台RS)
未开启4层ip透传时的访问测试极其日志
开启4层ip透传时的各种配置
nginx.conf(两台RS)
haproxy.cfg
开启4层ip透传时的访问测试极其日志:
ACL
HAProxy 的 ACL 是其核心功能之一,用于定义复杂的流量匹配规则,实现基于请求内容(如 URL、Header、IP、路径等)的智能路由、过滤或决策。
ACL基本语法
acl <acl_name> <匹配条件类型> <匹配参数> [标志]
acl名称(ACL-Name) —— 可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,并且严格区分大小写
匹配条件类型(ACL-criterion)—— 下面另外列表解释
匹配参数 —— 匹配的具体值(如 /api, User-Agent, 192.168.1.0/24)
标志 —— 可选修饰符(如 -i 忽略大小写,-m 匹配模式)
ACL-criterion 匹配规范
定义ACL匹配规范,即:判断条件
hdr string,提取在一个HTTP请求报文的首部
hdr([<name> [,<occ>]]):完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出
现次数
hdr_beg([<name> [,<occ>]]):前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [,<occ>]]):后缀匹配,header中指定匹配内容end
hdr_dom([<name> [,<occ>]]):域匹配,header中的dom(host)
hdr_dir([<name> [,<occ>]]):路径匹配,header的uri路径
hdr_len([<name> [,<occ>]]):长度匹配,header的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header中的uri模糊匹配 模糊匹配c 报文中a/b/c也会匹
配
#示例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.timinglee.org
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
#示例:
acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent
#有些功能是类似的,比如以下几个都是匹配用户请求报文中host的开头是不是www
acl short_form hdr_beg(host)
www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2 hdr_dom(host) -m beg www.
acl alternate3 hdr(host) -m beg www.
: exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
base : string
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base
path : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
path
: exact string match
path_beg : prefix match #请求的URL开头,如/static、/images、/img、/css
path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
#示例:
path_beg -i /haproxy-status/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom timinglee
url : string
#提取请求中的整个URL。
url :exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
dst
#目标IP
dst_port #目标PORT
src
#源IP
src_port #源PORT
#示例:
acl invalid_src src 10.0.0.7 192.168.1.0/24
acl invalid_src src 172.16.0.0/24
acl invalid_port src_port 0:1023
status : integer #返回在响应报文中的状态码
#七层协议
acl valid_method method GET HEAD
http-request deny if ! valid_method
自定义错误页面
对指定的报错进行重定向,进行优雅的显示错误页面
使用errorfile和errorloc指令的两种方法,可以实现自定义各种错误页面
#自定义错误页
errorfile <code> <file>
<code> #HTTP status code.支持200, 400, 403, 405, 408, 425, 429, 500, 502,503,504
<file> #包含完整HTTP响应头的错误页文件的绝对路径。 建议后缀".http",以和一般的html文件相区分
#示例:
errorfile 503 /haproxy/errorpages/503page.http
HAProxy 四层负载
HAProxy 是一个高性能、高可用性的负载均衡器和反向代理软件。它的四层负载均衡模式,通常称为 TCP 模式或 Layer 4 (L4) 模式,专注于在传输层(TCP) 工作。这意味着 HAProxy 在此模式下不解析应用层协议(如 HTTP)的内容,它只处理 TCP 连接本身。
实验——对 MySQL 服务实现四层负载
两台RS安装mariadb-server
结果
[root@Client ~]# mysql -ulee -plee -h 172.25.254.100 -e "show variables like 'hostname'"
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| hostname | hp-RS2 |
+---------------+--------+
[root@Client ~]# mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+------------+
| @@server_id |
+------------+
| 2 |
+------------+
[root@Client ~]# mysql -ulee -plee -h172.25.254.100 -e "select @@server_id"
+------------+
| @@server_id |
+------------+
| 1 |
+------------+
证书
证书制作
openssl req
这是 OpenSSL 的子命令,用于处理证书签名请求。虽然名字叫 req,但结合 -x509 选项时,它可以直接生成自签名证书,而无需先生成 CSR。
-newkey rsa:2048
-newkey:指示 OpenSSL 生成一个新的私钥。
rsa:2048:指定新私钥的算法为 RSA,密钥长度为 2048 位。这是目前广泛使用的安全标准。
-nodes
这个选项的意思是 "不要用密码加密私钥"。
如果省略 -nodes,OpenSSL 会在生成私钥时提示你设置一个密码。每次 HAProxy(或其他服务)启动使用这个私钥时,都需要输入密码,这对于自动启动的服务非常不便。
重要提示: 使用 -nodes 意味着私钥文件 (timinglee.org.key) 是未加密存储在磁盘上的。必须严格限制该文件的访问权限(通常设置为 600 或 400,仅限 root 或特定服务用户读取),否则存在安全风险。
-sha256
指定生成证书请求(以及最终证书)时使用的哈希算法为 SHA-256。
这是当前推荐的安全哈希算法,替代了较弱的 SHA-1 或 MD5。
-keyout /etc/haproxy/certs/timinglee.org.key
-keyout:指定新生成的私钥应保存到的文件路径和名称。
这里私钥将被保存到 /etc/haproxy/certs/timinglee.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/timinglee.org.crt
-out:指定生成的自签名证书应保存到的文件路径和名称。
这里证书将被保存到 /etc/haproxy/certs/timinglee.org.crt。
测试访问
[root@Client ~]# curl -Ikl http://172.25.254.100
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Wed, 23 Jul 2025 11:37:36 GMT
Content-Type: text/html
Content-Length: 5909
Last-Modified: Mon, 09 Aug 2021 11:43:42 GMT
Connection: keep-alive
ETag: "611114ee-1715"
Accept-Ranges: bytes