HAProxy 技术解析与负载均衡体系梳理
一、HAProxy 核心技术解析
HAProxy 作为开源领域的高性能代理工具,其设计理念和技术特性使其成为高并发场景的核心组件,以下从本质、优势、运行模型三方面展开
1. 本质与核心能力
HAProxy 是一款用C 语言编写的自由开源软件,核心价值在于 "三位一体" 的功能整合:
- 高可用性保障:通过后端节点健康检查(如 TCP 端口探测、HTTP 状态码检测)自动剔除故障服务器,同时支持主从备份架构,避免自身单点故障,确保服务持续可用
- 多层级负载均衡:同时支持 TCP 层(四层)和 HTTP 层(七层)负载均衡,可根据业务需求灵活选择转发策略(如轮询、加权轮询、IP 哈希等)
- 应用层安全代理:作为前端请求与后端服务器的 "中间层",可隐藏后端真实 IP,防止服务器直接暴露在公网,降低被攻击风险;同时支持 SSL 卸载(集中处理 HTTPS 加密解密),减轻后端服务器压力
2. 关键优势与适用场景
HAProxy 的特性使其尤其适配高负载、高要求的业务场景:
- 高并发支撑 :依托高效的底层设计,在普通硬件上即可稳定支持数万级并发连接,满足电商大促、社交平台高峰流量等场景需求
- 精细化业务适配:支持 "会话保持"(Sticky Session),通过 Cookie 或 IP 绑定,确保用户同一会话的请求始终转发至同一后端服务器(避免登录状态丢失);支持七层内容过滤(如按 URL 路径、Host 主机名路由请求)
- 低资源消耗:C 语言编译的轻量内核,内存占用低(通常仅数 MB),CPU 利用率高,避免资源浪费
其典型适用场景包括:
- 负载特大的 Web 站点(如 GitHub、Twitter 等流量密集型平台)
- 需要会话保持、内容路由的服务(如用户中心、API 网关)
- 需隐藏后端架构、提升安全性的公网服务(如面向用户的 Web 应用)
3. 运行模型:事件驱动单一进程的优劣势
HAProxy 采用事件驱动的单一进程模型,这是其高并发能力的核心,需结合传统多进程 / 多线程模型对比理解:
对比维度 | 事件驱动单一进程模型 | 传统多进程 / 多线程模型 |
---|---|---|
资源管理 | 无内存碎片,无进程间通信开销,资源利用率极高 | 每个进程 / 线程占用独立内存,系统调度切换开销大 |
并发处理上限 | 支持数万级并发,无锁竞争(单进程内事件循环) | 受锁限制,通常仅支持数千并发,易出现性能瓶颈 |
多核适配性 | 劣势:单一进程无法充分利用多核 CPU,需通过 "CPU 绑定" 优化 | 优势:可通过多进程 / 线程利用多核,但需解决锁竞争 |
简言之,该模型的核心是 "用高效的用户空间事件调度,替代操作系统级的进程调度",从而突破并发瓶颈,但需通过技术优化(如将 HAProxy 进程绑定到不同 CPU 核心)适配多核服务器
4. 行业实践验证
HAProxy 的稳定性和性能已得到全球顶级平台的认可,典型案例包括:
- 代码托管与技术社区:GitHub、Bitbucket、Stack Overflow
- 社交与内容平台:Reddit(论坛)、Tumblr(轻博客)、Twitter(社交)
- 云计算服务:亚马逊网络服务(AWS),用于部分服务的负载均衡与高可用保障
二、负载均衡层级体系与产品对比
负载均衡的 "层级" 对应 OSI 网络模型,不同层级的核心差异在于 "转发依据",直接决定其性能、灵活性与适用场景,以下按 "二层→三层→四层→七层" 逐一解析
1. 各层级负载均衡核心原理与特性
层级 | 对应网络层 | 核心原理 | 典型产品 | 适用场景 | 核心特点 |
---|---|---|---|---|---|
二层(MAC) | 数据链路层 | 配置虚拟 MAC 地址,外部请求指向虚拟 MAC,负载均衡器转发至后端真实 MAC 地址 | F5 BIG-IP(硬件)、华为交换机 | 同一局域网内的服务器集群(无需跨网段) | 转发效率极高,仅处理数据链路层帧,无跨网段能力 |
三层(IP) | 网络层 | 配置虚拟 IP(VIP),外部请求指向 VIP,负载均衡器转发至后端真实 IP 地址 | F5 BIG-IP、Linux IPVS(LVS) | 跨网段的服务器集群(如不同子网的应用节点) | 支持跨网段,仅基于 IP 转发,不区分端口 |
四层(TCP) | 传输层 | 在三层基础上,结合 "IP + 端口" 转发请求(如将 80 端口请求转发至后端 8080 端口) | F5 BIG-IP、LVS、Nginx(1.9+)、HAProxy | TCP/UDP 协议服务(如 MySQL、Redis、SSH) | 转发效率高,支持端口映射,不解析应用内容 |
七层(HTTP) | 应用层 | 解析应用层内容(如 URL、Host、Cookie),按规则转发(如/api 路径转发至 API 服务器) |
HAProxy、Nginx、Apache、MySQL Proxy | Web 服务、API 网关、需内容路由的场景 | 灵活性高,支持会话保持、SSL 卸载,解析应用内容导致开销略高 |
2. HAProxy 在负载均衡体系中的定位
HAProxy 是少数能同时覆盖四层与七层的负载均衡工具,其定位优势体现在:
- 对比 LVS(纯四层):HAProxy 支持七层内容解析,可实现 URL 路由、会话保持等精细化功能,灵活性更强
- 对比 Nginx(以七层为主):HAProxy 的四层转发性能更优,在高并发会话保持场景下(如电商购物车)稳定性更高
- 核心适配场景:需要 "四层性能" 与 "七层灵活性" 结合的业务(如高并发 Web 服务、需 SSL 卸载的 HTTPS 应用、多路径路由的 API 网关)
三、总结:HAProxy 与负载均衡选型建议
- HAProxy 的核心价值:高并发支撑、多层级负载均衡、安全代理,是高负载 Web 服务与复杂业务场景的优选工具;
- 负载均衡层级选型原则:
- 追求极致性能(如 TCP 服务):优先选四层负载均衡(LVS、HAProxy 四层模式)
- 需精细化内容路由(如 Web 服务):优先选七层负载均衡(HAProxy、Nginx)
- 局域网内简单转发:可选二层 / 三层负载均衡(硬件交换机、LVS 三层模式)
- 实际架构建议:大型系统常采用 "四层 + 七层" 组合(如 LVS 做四层入口,HAProxy/Nginx 做七层路由),兼顾性能与灵活性
示例:
haproxy安装:
配置本地yum仓库,部署httpd
RS1:
[root@rs1 ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 is write-protected, mounting read-only
[root@rs1 ~]# cd /etc/yum.repos.d/
[root@rs1 yum.repos.d]# ls
CentOS-Base.repo CentOS-fasttrack.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-Media.repo
CentOS-Debuginfo.repo CentOS-Sources.repo
[root@rs1 yum.repos.d]# rm -rf *
[root@rs1 yum.repos.d]# vim sy.repo
[aa]
name=aa1
baseurl=file:///mnt
enabled=1
gpgcheck=0
~
[root@rs1 ~]# yum -y install httpd
[root@rs1 ~]# echo RS1 > /var/www/html/index.html
[root@rs1 ~]# systemctl restart httpd
[root@rs1 ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
RS2:
[root@rs2 ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 is write-protected, mounting read-only
[root@rs2 ~]# cd /etc/yum.repos.d/
[root@rs2 yum.repos.d]# ls
CentOS-Base.repo CentOS-fasttrack.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-Media.repo
CentOS-Debuginfo.repo CentOS-Sources.repo
[root@rs2 yum.repos.d]# rm -rf *
[root@rs2 yum.repos.d]# vim sy.repo
[aa]
name=aa1
baseurl=file:///mnt
enabled=1
gpgcheck=0
~
[root@rs2 ~]# yum -y install httpd
[root@rs2 ~]# echo RS2 > /var/www/html/index.html
[root@rs2 ~]# systemctl restart httpd
[root@rs2 ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
server:
[root@server ~]# curl http://192.168.100.20
RS1
[root@server ~]# curl http://192.168.100.30
RS2
server:(配置本地yum仓库)
[root@server ~]# cd /etc/yum.repos.d/
[root@server yum.repos.d]# ls
CentOS-Base.repo CentOS-fasttrack.repo CentOS-Vault.repo
CentOS-CR.repo CentOS-Media.repo
CentOS-Debuginfo.repo CentOS-Sources.repo
[root@server yum.repos.d]# rm -rf *
[root@server yum.repos.d]# vim sy.repo
[aa]
name=aa1
baseurl=file:///mnt
enabled=1
gpgcheck=0
~
[root@server yum.repos.d]# mount /dev/cdrom /mnt/
mount: /dev/sr0 is write-protected, mounting read-only
安装编译环境:
server:
[root@server ~]# yum -y install make gcc pcre-devel bzip2-devel openssl-devel systemd-devel gcc-c++ zlib-devel lua
创建haproxy用户:
[root@server ~]# useradd -r -M -s /sbin/nologin haproxy
上传压缩包:
[root@server ~]# rz -E
rz waiting to receive.
[root@server ~]# ls
anaconda-ks.cfg Downloads Music Templates
Desktop haproxy-2.1.3.tar.gz Pictures Videos
Documents initial-setup-ks.cfg Public
解压和安装:
[root@server ~]# tar -xzvf haproxy-2.1.3.tar.gz
[root@server ~]# ls
anaconda-ks.cfg haproxy-2.1.3 Pictures
Desktop haproxy-2.1.3.tar.gz Public
Documents initial-setup-ks.cfg Templates
Downloads Music Videos
[root@server ~]# cd haproxy-2.1.3/
[root@server haproxy-2.1.3]# make clean
[root@server haproxy-2.1.3]# make -j $(grep 'processor' /proc/cpuinfo |wc -l) \
> TARGET=linux-glibc \
> USE_OPENSSL=1 \
> USE_ZLIB=1 \
> USE_PCRE=1 \
> USE_SYSTEMD=1
....
[root@server haproxy-2.1.3]# make install PREFIX=/usr/local/haproxy
....
[root@server haproxy-2.1.3]# cp haproxy /usr/sbin/
设置Linux内核参数:
[root@server haproxy-2.1.3]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
~
[root@server haproxy-2.1.3]# sysctl -p
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
配置haproxy服务:
[root@server haproxy-2.1.3]# mkdir /etc/haproxy
[root@server haproxy-2.1.3]# vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0 info
#log loghost local0 info
maxconn 20480
#chroot /usr/local/haproxy
pidfile /var/run/haproxy.pid
#maxconn 4000
user haproxy
group haproxy
daemon
#---------------------------------------------------------------------
#common defaults that all the 'listen' and 'backend' sections will
#use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option dontlognull
option httpclose
option httplog
#option forwardfor
option redispatch
balance roundrobin
timeout connect 10s
timeout client 10s
timeout server 10s
timeout check 10s
maxconn 60000
retries 3
#--------------统计页面配置------------------
listen admin_stats
bind 0.0.0.0:8189
stats enable
mode http
log global
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
stats auth admin:admin
#stats hide-version
stats admin if TRUE
stats refresh 30s
#---------------web设置-----------------------
listen webcluster
bind 0.0.0.0:80
mode http
#option httpchk GET /index.html
log global
maxconn 3000
balance roundrobin
cookie SESSION_COOKIE insert indirect nocache
server rs1 192.168.100.20:80 check
server rs2 192.168.100.30:80 check
启动haproxy,配置haproxy.service服务单元文件:
[root@server ~]# vim /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target
[Service]
ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
ExecReload=/bin/kill -USR2 $MAINPID
[Install]
WantedBy=multi-user.target
~
[root@server ~]# systemctl daemon-reload
配置日志信息:
[root@server ~]# vim /etc/rsyslog.conf
....
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none /var/log/messages
local0.* /var/log/haproxy.log
# The authpriv file has restricted access.
....
[root@server ~]# systemctl restart rsyslog
[root@server ~]# systemctl enable rsyslog
[root@server ~]# systemctl restart haproxy
[root@server ~]# systemctl enable haproxy
Created symlink from /etc/systemd/system/multi-user.target.wants/haproxy.service to /usr/lib/systemd/system/haproxy.service.

刷新:


密码:admin
状态信息

配置文件解析:
haproxy 的配置文件由两部分组成:全局设定和对代理的设定,共分为五段:global,defaults,frontend,backend,listen
global: 全局配置,主要用于定义全局参数,属于进程级的配置,通常和操作系统配置有关
default: 配置默认参数,这些参数可以被用到frontend,backend,Listen组件
frontend:接收请求的前端虚拟节点,frontend可以指定具体使用后端的backend
backend : 后端服务集群的配置,真实服务器,一个backend对应一个或者多个实体服务器
listen: fronted和backend的组合体,比如haproxy实例状态监控部分配置。Haproxy1.3之前的唯一配置方式。
时间格式:
一些包含了值的参数表示时间,如超时时长。这些值一般以毫秒为单位,但也可以使用其它的时间单位后缀
us: 微秒(microseconds),即1/1000000秒
ms: 毫秒(milliseconds),即1/1000秒
s: 秒(seconds)
m: 分钟(minutes)
h:小时(hours)
d: 天(days)
全局global配置:
global
log 127.0.0.1 local0 info //定义haproxy日志输出设置
#log loghost local0 info //定义haproxy日志级别
maxconn 20480 //定义最大连接数
#chroot /usr/local/haproxy //chroot运行路径
pidfile /var/run/haproxy.pid //haproxy进程PID文件
#maxconn 4000
user haproxy //运行haproxy用户,可用uid代替
group haproxy //运行haproxy用户组,可用gid代替
daemon //以后台形式运行haproxy
级别 | 代码 | 描述 |
---|---|---|
energ | 0 | 系统不可用 |
alert | 1 | 必须马上采取行动的事件 |
crit | 2 | 关键的事件 |
err | 3 | 错误事件 |
warning | 4 | 警告事件 |
notice | 5 | 普通但重要的事件 |
info | 6 | 有用的信息 |
debug | 7 | 调试信息 |
defaults配置:
用于设置配置默认参数,这些参数可以被用到frontend,backend,listen组件
在此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中。如果某些参数属于公用的配置,只需要在defaults部分添加一次即可。而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,defaults部分参数对应的值自动被覆盖
defaults
mode http //所处理的类别(7层代理http,4层代理tcp)
log global //引入global定义的日志格式
option dontlognull //不记录健康检查日志信息
option httpclose //每次请求完毕后主动关闭http通道,haproxy不支持keep-alive模式
option httplog //日志类别为http日志格式
#option forwardfor //如果后端服务器需要获取客户端的真实ip,需要配置的参数,可以从http header中获取客户端的ip
option redispatch
balance roundrobin //设置默认负载均衡方式,轮询方式
timeout connect 10s //默认连接超时时间
timeout client 10s //默认客户端超时时间
timeout server 10s //默认服务器超时时间
timeout check 10s //设置超时检查超时时间
maxconn 60000 //最大连接数
retries 3 //3次连接失败就认为服务器不可用,也可以通过后面设置
mode http:设置haproxy的运行模式,有三种{http|tcp|health}。注意:如果haproxy中还要使用4层的应用(mode tcp)的话,不建议在此定义haproxy的运行模式
tcp模式:在此模式下,客户端和服务器端之前将建立一个全双工的连接,不会对七层报文做任何检查,默认为tcp模式,经常用于SSL、SSH、SMTP等应用
http模式:在此模式下,客户端请求在转发至后端服务器之前将会被深度分板,所有不与RFC格式兼容的请求都会被拒绝
health:已基本不用了
frontend配置:
frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。forntend可以根据ACL规则直接指定要使用的后端backend
如:
frontend http_80_in
bind 0.0.0.0:80 //设置侦听端口,即haproxy提供的web服务端口,和lvs的vip类似
mode http
log global
option httpclose
option httplog
option forwardfor
default_backend wwwpool //设置请求默认转发的后端服务池
backend配置:
用来定义后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器
backend wwwpool //定义wwwpool服务器组
mode http
option redispath
option abortonclose
balancer source //负载均衡的方式,源哈希算法
cookie SERVERID //允许插入serverid到cookie中,serverid后面可以定义
option httpdchk GET /test.html //心跳测试
server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maconn 8
listen配置:
常常用于状态页面监控,以及后端server检查,是Fronted和backend的组合体
listen admin_stats //frontend和backend的组合体,监控组的名称,按需自定义名称
bind 0.0.0.0:8189 //侦听端口
stats enable //开启监控
mode http
log global
stats uri /haproxy_stats //监控页面的url访问路径
stats realm Haproxy\ Statistics //监控页面的提示信息
stats auth admin:admin //监控页面的用户和密码
#stats hide-version //隐藏统计页面上的haproxy版本信息
stats admin if TRUE //手工启用/禁用,后端服务器haproxy
2 fall 3 maconn 8
listen配置:
常常用于状态页面监控,以及后端server检查,是Fronted和backend的组合体
listen admin_stats //frontend和backend的组合体,监控组的名称,按需自定义名称
bind 0.0.0.0:8189 //侦听端口
stats enable //开启监控
mode http
log global
stats uri /haproxy_stats //监控页面的url访问路径
stats realm Haproxy\ Statistics //监控页面的提示信息
stats auth admin:admin //监控页面的用户和密码
#stats hide-version //隐藏统计页面上的haproxy版本信息
stats admin if TRUE //手工启用/禁用,后端服务器haproxy
stats refresh 30s //每个30秒自动刷新监控页面