一、Haproxy 七层代理
(一)负载均衡
1.概念
负载均衡是一种通过软件服务或硬件设备实现的高可用反向代理技术,其核心作用是将特定的业务负载(如Web服务、网络流量等)智能地分发到一个或多个后端服务器上。通过这种分担机制,负载均衡实现了三大目标:提升并发处理能力(让更多请求同时被处理)、保证业务高可用性(单台服务器故障不影响整体服务)以及支持水平动态扩展(只需增加服务器即可提升系统容量),是现代大规模网站架构的基石。

2.特点
支持 Web 服务器的动态水平扩展,在增加或减少后端服务器时对用户完全无感知,不影响在线服务;通过将请求分发到多台服务器,有效解决单服务器瓶颈问题,大幅提升业务并发访问及处理能力;同时支持多台内网服务器共用同一个公网 IP 对外提供服务,节约公网 IP 地址从而降低 IT 支出成本,并且隐藏内部服务器 IP,有效提高内部服务器安全性;其配置采用固定格式的配置文件,配置简单、易于维护;功能方面支持四层和七层负载均衡,支持动态下线故障主机,功能丰富;性能上可轻松处理数万甚至数十万并发连接,性能强劲,能够满足大规模业务场景的需求。
3.类型
(1)硬件
F5 美国F5网络公司 https://f5.com/zh
Netscaler 美国思杰公司 https://www.citrix.com.cn/products/citrix-adc/、
Array 华耀 https://www.arraynetworks.com.cn/
AD-1000 深信服 http://www.sangfor.com.cn/
(2)四层负载均衡

四层负载均衡工作于 OSI 模型的传输层,基于IP地址和端口号(ip+port)决定流量的转发去向。其核心工作原理是对请求报文进行 NAT 处理:修改报文头部的目标地址(DNAT),必要时按需修改源地址(SNAT),然后将流量转发至后端服务器。同时,四层负载均衡器会记录 TCP/UDP 连接的状态,确保同一连接的后继流量始终由同一台后端服务器处理,保持会话一致性。
常见的四层负载均衡软件包括:
LVS:重量级四层负载均衡器,集成于 Linux 内核,性能极高,稳定可靠
Nginx:轻量级四层负载均衡器(通过 stream 模块实现),支持缓存功能,配置灵活
HAProxy:支持四层转发(模拟四层),功能丰富,配置简单
(3)七层负载均衡

七层负载均衡工作于 OSI 模型的应用层,其核心机制是代理功能:负载均衡器作为中间代理,与客户端建立独立的 TCP 连接,同时与后端服务器建立另一条独立的 TCP 连接,实现前后端连接的解耦。
在流量调度方面,七层负载均衡通过虚拟 URL、主机名或 HTTP 头部等应用层信息进行流量识别和解析,根据预设规则决定是否需要进行负载均衡及转发到哪台后端服务器。这使得七层负载均衡能够实现更精细的流量管理,如基于域名、URL 路径、Cookie 等的分发策略。
常见的七层负载均衡软件包括:
Nginx:基于 HTTP 协议的七层代理,通过 proxy_pass 实现反向代理和负载均衡,配置灵活,支持缓存、重写等功能
HAProxy:功能强大的七层代理,支持会话保持、标记、路径转移等高级特性,适用于复杂的应用层流量管理场景
(4)四层和七层区别
所谓四到七层负载均衡,是指在对后端服务器进行流量分发时,依据四层(传输层)信息或七层(应用层)信息来决定转发策略。
四层负载均衡工作在传输层及以下,通过发布三层的VIP(虚拟IP)结合四层的端口号来识别需要处理的流量,对符合条件的请求进行NAT转换后转发至后端服务器,并记录TCP/UDP连接状态,确保同一连接的所有后续流量都转发到同一台服务器处理。其优势在于:性能较高(无需解析报文内容,网络吞吐量大)、原理简单(基于IP+端口,类似于路由器功能),但安全性较弱(无法识别应用层DDoS攻击)。
七层负载均衡工作在应用层及以下,建立在四层基础之上(没有四层就没有七层),除了依据VIP和端口识别流量外,还会解析应用层信息(如URL、浏览器类别、Cookie、HTTP头部等)来决定负载均衡策略。其优势在于:功能丰富(支持基于内容的路由、会话保持等)、安全性较高(可防御SYN Cookie/Flood等应用层攻击),但性能相对较低(需要解析报文内容,类似于代理服务器功能)。
(二)Haproxy 简介
1.概念
HAProxy 是由法国开发者威利塔罗(Willy Tarreau)于2000年使用C语言开发的开源负载均衡软件,具备高并发(万级以上)和高性能的 TCP/HTTP 负载均衡能力。它支持基于 Cookie 的持久性实现会话保持,具备自动故障切换机制保障业务高可用,支持正则表达式实现灵活路由,并提供直观的 Web 状态统计页面,是构建高可用、高并发业务系统的核心组件。


2.基本配置信息
HAProxy 的配置文件 haproxy.cfg 由两大部分组成,分别是:
global:全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug 参数
proxies:代理配置段
defaults:为 frontend, backend, listen 提供默认配置
frontend:前端,相当于 nginx 中的 server {}
backend:后端,相当于 nginx 中的 upstream {}
listen:同时拥有前端和后端配置,配置简单,生产推荐使用
(1)global 配置
参数说明:


(2)proxies 配置
参数说明:
|----------|---------------------------------------------------------------|
| 参数 | 作用 |
| defaults | 默认配置项,针对以下的 frontend、backend 和 listen 生效,可以多个 name 也可以没有 |
| frontend | 前端 servername,类似于 Nginx 的一个虚拟主机 server 和 LVS 服务集群。 |
| backend | 后端服务器组,等于 nginx 的 upstream 和 LVS 中的 RS 服务器 |
| listen | 将 frontend 和 backend 合并在一起配置,相对于 frontend 和backend 配置更简洁,生产常用 |
注意:name 字段只能使用大小写字母,数字,'-'(dash),'_'(underscore),'.' (dot)和 ':'(colon),并且严格区分大小写
defaults 配置参数:



frontend 配置参数:

backend 配置参数:

server 配置:


(3)socat 工具
对服务器动态权重和其它状态可以利用 socat 工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是 Socket CAT,相当于 netCAT 的增强版 .Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、Socket 文件等

(三)haproxy 算法
HAProxy 通过 balance 参数指定后端服务器的调度算法,可配置于 listen 或 backend 段中。调度算法分为静态算法(不实时调整后端权重)和动态算法(可根据服务器负载动态调整权重),部分算法如 static-rr 可通过参数在静态和动态间相互转换,常见的调度算法包括轮询(roundrobin)、最少连接(leastconn)、源地址哈希(source)等,管理员可根据业务场景选择合适的算法来优化负载分发效率。
1.静态算法
严格按照预设规则调度,不关注后端服务器的实时负载或响应速度。其权重只能设为0或1(0下线,1在线),任何修改必须重启 HAProxy 才能生效。常见的静态算法有 static-rr(静态轮询)和first(优先调度第一台),适用于后端性能一致且无需动态调整的场景,但缺乏灵活性,在负载波动时难以实现最优资源利用。
(1)static-rr
不支持运行时利用 socat 进行权重的动态调整(只支持0和1,不支持其它值)
不支持端服务器慢启动
其后端主机数量没有限制,相当于 LVS 中的 wrr
(2)first
根据服务器在列表中的位置,自上而下进行调度
其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
其会忽略服务器的权重设置
不支持用 socat 进行动态修改权重,可以设置0和1,可以设置其它值但无效
2.动态算法
动态算法会根据后端服务器的实时状态进行智能调度,新请求优先分发到当前负载较低、连接数较少或响应速度较快的服务器。其最大优势是支持运行时通过 socat 等工具动态调整权重,无需重启 HAProxy 即可生效,能够根据业务负载变化实时优化资源分配。常见的动态算法包括roundrobin(动态轮询)、leastconn(最少连接)和source(源地址哈希)等,适用于后端服务器性能不均或业务流量波动较大的场景,能有效提升整体系统的吞吐量和稳定性。
(1)roundrobin
基于权重的轮询动态调度算法,
支持权重的运行时调整,不同于 lvs 中的 rr 轮训模式,
HAProxy 中的 roundrobin 支持慢启动(新加的服务器会逐渐增加转发数),
其每个后端 backend 中最多支持4095个 real server,
支持对 real server 权重动态调整,
roundrobin 为默认调度算法,此算法使用广泛
(2)leastconn
leastconn 加权的最少连接的动态
支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
比较适合长连接的场景使用,比如:MySQL 等场景。
3.其他算法
其它算法即可作为静态算法,又可以通过选项成为动态算法
(1)source
源地址 hash,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端 web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过 hash-type 支持的选项更改这个算法一般是在不插入 Cookie 的 TCP 模式下使用,也可给拒绝会话 cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持 cookie 和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性 hash
map-bass 取模法:
map-based(取模法)是一种静态哈希调度算法,通过对源地址进行哈希计算后,基于服务器总权重取模来决定请求转发目标。该算法为静态模式,不支持在线调整权重和慢启动机制,虽然能够实现均衡调度,但当后端服务器总权重发生变化(如上线或下线服务器)时,会导致整个哈希映射结果改变,从而影响客户端访问的一致性。这是 HAProxy 中 hash-type 参数的默认算法。
注意:
所谓取模运算,就是计算两个数相除之后的余数,10%7=3, 7%4=3。而 map-based 算法则是基于权重取模,hash(source_ip)% 所有后端服务器相加的总权重------
比如当源 hash 值时1111,1112,1113,三台服务器 a b c 的权重均为1,
即abc的调度标签分别会被设定为 0 1 2(1111%3=1,1112%3=2,1113%3=0)
1111 ----- > nodeb
1112 ------> nodec
1113 ------> nodea
如果 a 下线后,权重数量发生变化
1111%2=1,1112%2=0,1113%2=1
1112和1113被调度到的主机都发生变化,这样会导致会话丢失
一致性 hash:
一致性哈希算法通过哈希映射的方式将请求分配到后端服务器,其最大特点是当服务器总权重发生变化(如上线或下线)时,仅影响局部请求的调度结果,不会引起全局重新分配,从而保持较好的稳定性。该算法属于动态算法,支持运行时通过 socat 等工具在线调整权重,同时也支持慢启动机制,适用于后端服务器频繁变更或需要平滑扩缩容的场景,能够在保证调度均衡的同时最大限度地减少对现有连接的影响。



hash 对象到后端服务器的映射关系:

hash 示意图:

(2)uri
uri 算法基于用户请求的 URI(左半部分或整个URI)进行哈希计算,将结果对后端服务器总权重取模后决定转发目标,适用于缓存服务器场景以实现请求亲和性。该算法默认为静态模式(map-based 取模法),但可以通过hash-type参数指定使用 consistent(一致性哈希)来动态调整,从而在后端服务器变动时仅局部影响调度结果,提升稳定性。
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp


(3)url_param
url_param 算法根据用户请求 URL 中指定参数 key 的 value 值进行哈希计算,再将结果对后端服务器总权重取模后决定转发目标,可实现同一用户的请求始终发往同一台后端服务器,常用于电商等需要追踪用户会话的场景。如果请求中不存在指定的参数 key,则默认使用 roundrobin 算法进行轮询调度。该算法默认为静态模式(map-based),但可通过 hash-type 参数调整为一致性哈希,以降低后端服务器变动时的影响范围。

(4)hdr
hdr 算法针对用户请求中指定 HTTP 头部(header)字段的值进行哈希计算,将结果对后端服务器总权重取模后决定转发目标,可用于实现基于特定头部信息的会话保持。如果请求中不存在指定的头部或值为空,则默认使用 roundrobin 算法进行轮询调度。该算法默认为静态模式,但可通过hash-type 参数调整为一致性哈希,适用于需要根据 User-Agent、Referer 等头部信息进行精细化调度的场景。
4.算法总结
静态:
static-rr--------->tcp/http
first------------->tcp/http
动态:
roundrobin-------->tcp/http
leastconn--------->tcp/http
random------------>tcp/http
以下静态和动态取决于 hash_type 是否 consistent:
source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http
各算法使用场景:

(四)高级功能及配置
1.基于 cookie 的会话保持
cookie value:为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了 haproxy 负载,目前此模式使用较少, 已经被 session 共享服务器代替

2.haproxy 状态页

登录状态页参数说明:

backend server 信息:

3.IP透传
web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景。
(1)四层 IP 透传
四层 IP 透传是指在 TCP/UDP 层负载均衡场景下,让后端真实服务器能够获取到客户端的真实 IP 地址,而不是看到负载均衡器的内网 IP。 由于负载均衡器会替代客户端与后端服务器建立连接,默认情况下后端服务器只能看到负载均衡器的源 IP,导致无法记录真实客户端日志、无法基于客户端 IP 做访问控制。常见的解决方案包括 Proxy Protocol 协议(在 TCP 连接建立后插入客户端真实IP和端口信息,需负载均衡器和后端应用同时支持)、TOA(TCP Option Address)内核模块(将客户端 IP 写入 TCP 选项字段)以及直接路由(DR)模式(保持原IP不变)。这些技术广泛应用于需要客户端 IP 审计、安全策略或个性化服务的场景。
(2)七层 IP 透传
七层 IP 透传是指在 HTTP/HTTPS 应用层负载均衡场景下,让后端 Web 服务器能够获取到客户端的真实 IP 地址。由于七层负载均衡器作为反向代理,会代替客户端与后端服务器建立连接,导致后端服务器默认只能看到负载均衡器的源 IP。最常用的解决方案是 X-Forwarded-For(XFF)请求头,负载均衡器将客户端真实 IP 添加在该头部中传递;此外还有 X-Real-IP 和 PROXY Protocol 等方式。后端 Web 服务器(如 Nginx、Apache、Tomcat)需要相应配置以读取这些头部信息,从而记录真实客户端日志、实施基于IP的访问控制或进行地理位置分析。

4.ACL
访问控制列表(ACL)是一种基于包过滤的访问控制技术,通过对经过服务器的数据包进行条件匹配和过滤,实现对请求的精细化管理。ACL 可以根据请求报文头部中的多种信息进行匹配,包括源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等内容。匹配成功后,可以执行进一步操作,如允许通过、拒绝访问、定向到特定后端等。在 HAProxy 等负载均衡器中,ACL 常用于实现基于内容的路由、访问权限控制、安全防护和流量治理等功能,是灵活控制业务流量的重要手段。
(1)配置选项
用 acl 来定义或声明一个 acl
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
(2)名称

(3)匹配规范


(4)匹配模式
-i 不区分大小写
-m 使用指定的正则表达式匹配方法
-n 不做 DNS 解析
-u 禁止 acl 重名,否则多个同名 ACL 匹配或关系
(5)具体操作符

(6)操作对象

5.自定义错误界面
HAProxy 通过 errorfile 和 errorloc 指令实现自定义错误页面,在发生指定 HTTP 错误时进行优雅的重定向显示。
errorfile:使用本地文件返回自定义错误页面,将预定义的 HTML 错误页面文件直接嵌入 HAProxy 配置中,适用于静态错误页面的快速返回。
errorloc:将错误重定向到指定的 URL 地址,当错误发生时自动跳转到预设的外部错误页面服务器,适用于集中管理和动态更新错误页面。

(1)基于自定义的错误页面文件

(2)基于 http 重定向错误页面

(五)haproxy 实践
1.实验环境
|------------|-------|----------------------------------------------------|-----------------------------------------------|
| 主机名 | 角色 | IP | 作用 |
| haproxy | 负载均衡器 | eth0:172.168.75.100(vip) eth1:192.168.220.100(dip) | vip:对外提供负载均衡服务,接收客户端请求 dip:与后端 Web 服务器通信的内网接口 |
| webserver1 | 后端服务器 | eth0:192.168.220.10(rip) | 实际处理业务请求的 Web 服务器1 |
| webserver2 | 后端服务器 | eth0:192.168.220.20(rip) | 实际处理业务请求的 Web 服务器2 |
haproxy
配置内核路由功能:

web1


web2
和 web1 一样安装 http

验证

2.安装及配置参数
准备工作:


(1)实现最基本的负载
前后端分开设定(把原有的注释后写入):


测试:

用 listen 方式书写负载均衡:

测试:

(2)发送日志
在 web1 开启接受日志的端口:


查看接受日志端口是否开启:

在 haproxy 主机中设定日志发送信息:



验证:

此时 web1 会发生以下情况,web2 无影响:

也可直接查看日志信息:


(3)实现多进程
默认的 haproxy 是单进程:



验证:

多进程 cpu 绑定:


为不同进程准备不同套接字:



(4)实现多线程
查看 haproxy 子进程的线程信息:

启用多线程:

验正:

3.算法实验
(1)static-rr

验证:

检测是否支持热更新:



如果不成功,试着把权限放宽:


(2)first

验证(一直等着,期间会出一条 web2 的信息):

(3)roundrobin

验证:

动态权重更新:

验证:

(4)leastconn

验证:

(5)uri
web1:

web2:

设定 uri 算法:

验证:

(6)url_param
web1 和 web2 设置同上
设定 url_param 算法:

验证:

(7)hdr

验证:

4.状态页



登录测试:


开启自动刷新:

5.自定义错误界面
(1)sorryserver 的设定
正常的所有服务器如果出现宕机,那么客户将被定向到指定的主机中,这个当业务主机出问题时被临时访问的主机叫做 sorryserver。
在主机中安装 apache:




配置 sorryserver 上线:

验证:

关闭两台正常的业务主机(web1、web2):


(2)错误页面
当所有主机包括 sorryserver 都宕机了,那么 haproxy 会提供一个默认访问的错误页面,这个错误页面跟报错代码有关,这个页面可以通过定义来机型设置。
将三台主机的 http 服务停掉

所有后端 web 服务都宕机:

写入页面:


在 /etc/haproxy/haproxy.cfg 里:

验证:

6.四层负载
(1)环境设定
部署 mariadb 数据库(以下操作 web1 和 web2均要):




web1 id 为10,web2 为20:

建立远程登录用户并授权(ctrl d 可退出):

测试:


四层负载操作:


检测端口:

测试(新开一个窗口,quit 退出):

退出重新登录,再次查找会显示另一台主机的 id 号:

(2)backup 参数


测试:

这次退出重新登录,查找 id 号不变:

此时需要关闭 web1 的 mariadb 并等待1分钟,出现另一台主机的 id 号:


想要原先 web1 主机,还原后等待片刻即可:


7.ACL 访问控制
(1)实验准备
在 Linux 或 Windows 中设定解析:
Windows:
以管理员身份打开记事本,选择左上角的"文件","打开",点击 c 盘里面的"Windows"------"System32"------"drivers"------"etc"。选择"hosts"文件打开即可:

在记事本末尾写入下列内容,保存:

验证(命令提示符):

linux(新开一个窗口):


ping 一下域名,看是否能通
(2)设定基础配置


(3)基础 acl 示例
在访问的网址中,所有以.com 结尾的访问 web1,其他访问 web2:


测试:

再新开一个窗口:

base 参数 acl:


三台主机都要:

分别写入页面:


测试:

acl 禁止列表黑名单:

测试(只有 web2):

禁止列表白名单:

测试:
