haproxy原理及实战部署
一、负载均衡
负载均衡是网络架构和分布式系统中至关重要的技术,其核心作用是将大量的并发请求或数据流量合理分配到多个服务器(或其他资源节点)上,从而解决单节点压力过大、资源利用率低、系统稳定性差等问题。
作用
1. 提高系统吞吐量和并发处理能力
负载均衡通过将请求分散到多台服务器,让每台服务器处理的请求量控制在合理范围内,整体提升系统的并发处理能力
2. 避免单点故障,增强系统可用性
负载均衡会实时监测后端服务器的健康状态(如通过心跳检测、请求响应时间等),当某台服务器故障时,自动将请求转发到其他正常服务器,确保服务不中断,显著提高系统的可用性。
3. 优化资源利用率,降低成本
负载均衡通过合理分配请求,让所有服务器的资源(CPU、内存等)得到均衡利用,避免资源闲置,从而在满足业务需求的前提下,减少不必要的服务器投入成本。
4. 提升用户体验(降低响应延迟)
负载均衡将请求分配给负载较轻的服务器,保证每台服务器都能快速处理请求,降低整体响应延迟,提升用户体验。
5. 支持业务扩展(弹性伸缩)
当业务增长(如电商大促、直播峰值)时,只需通过负载均衡新增服务器节点,即可无缝扩展系统处理能力,无需修改核心架构。
反之,业务低谷时可减少服务器节点,通过负载均衡自动调整流量分配,实现资源的弹性伸缩。
6. 增强安全性(辅助防护)
过滤恶意请求(如 DDoS 攻击的流量清洗);
隐藏后端服务器的真实 IP 地址,减少直接暴露在公网的风险;
支持 SSL/TLS 加密,处理 HTTPS 请求的解密 / 加密工作,减轻后端服务器负担。
四层负载均衡
原理
四层负载均衡工作在传输层,其转发逻辑依赖于数据包的源 IP、目标 IP、源端口、目标端口以及协议类型(TCP/UDP) 等信息。
- 当客户端请求到达负载均衡器时,负载均衡器会分析数据包的上述四层信息,根据预设策略(如轮询、源 IP 哈希等)选择后端服务器;
- 随后,负载均衡器会修改数据包的目标 IP 和端口(替换为选中的后端服务器 IP 和端口),并将数据包转发给该服务器;
- 服务器处理完成后,响应数据包会原路返回负载均衡器,再由负载均衡器修改源 IP 和端口(替换为自身的 IP 和端口),最终返回给客户端。
整个过程中,负载均衡器不会解析数据包的具体内容(如 HTTP 请求的 URL、参数等),仅基于传输层信息进行转发,因此速度更快、开销更低。
支持软件
- vs:重量级四层负载均衡器。
- Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块)
- Haproxy:模拟四层转发。
七层负载均衡
原理
七层负载均衡工作在应用层,其转发逻辑依赖于对请求内容的深度解析:
- 当客户端请求到达负载均衡器时,负载均衡器会先 “拆开” 数据包,解析应用层协议的具体内容(例如,HTTP 请求的
/api/user
路径、Host
头、Cookie
信息等); - 根据预设的应用层策略(如 “URL 路径匹配”“请求头关键字”“用户身份” 等),选择最合适的后端服务器;
- 将请求转发到选中的服务器,同时可能对请求内容进行修改(如添加 / 删除请求头、重写 URL);
- 服务器响应后,负载均衡器再将响应返回给客户端,过程中也可对响应内容进行处理(如压缩、添加响应头)。
支持软件
- Nginx:基于http协议(nginx七层是通过proxy_pass)
- Haproxy:七层代理,会话保持、标记、路径转移等。
四层和七层区别
维度 | 四层负载均衡 | 七层负载均衡 |
---|---|---|
工作层级 | 传输层(TCP/UDP) | 应用层(如 HTTP、HTTPS) |
转发依据 | IP、端口、协议 | URL、HTTP 头部、Cookie 等应用层信息 |
性能 | 高(无需解析应用数据) | 较低(需解析应用层内容) |
灵活性 | 较低(策略基于网络层信息) | 较高(可根据应用逻辑定制策略) |
会话保持 | 依赖源 IP 哈希等简单方式 | 支持基于 Cookie、Session 的精准保持 |
典型应用 | 数据库连接、视频流、UDP 服务 | Web 服务器、API 网关、HTTPS 请求调度 |
二、haproxy简介
HAProxy(High Availability Proxy)是一款由法国人Willy Tarreau开发的高性能、开源的TCP和HTTP负载均衡器。它使用C语言编写,具备高并发处理能力和丰富的功能特性,广泛应用于各种需要高负载和高可用性的Web站点和应用程序中。
开发者:Willy Tarreau
类型:高性能的TCP和HTTP负载均衡器
特点:免费、快速、可靠
主要功能:负载均衡、健康检查、会话保持、SSL/TLS支持、HTTP重写、压缩等
三、haproxy安装
安装
dnf install haproxy -y
版本查看
[root@haproxy ~]# haproxy -v
HAProxy version 2.4.22-f8e3218 2023/02/14 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2026.
Known bugs: http://www.haproxy.org/bugs/bugs-2.4.22.html
Running on: Linux 5.14.0-427.13.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 10 10:29:16 EDT 2024 x86_64
基本信息
软件安装包: 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基本配置信息
1.global-全局配置
全局配置影响 HAProxy 进程的整体行为,如日志、权限、资源限制等。
log <地址> <设备>
定义全局的syslog服务器;日志服务器需要开启UDP协议,最多可以定义两个
chroot <路径>
为 HAProxy 进程设置根目录(安全加固,限制进程访问范围),通常为 /var/lib/haproxy。
pidfile <路径>
指定pid文件
stats socket <路径> [参数]
定义统计信息的 Unix 套接字路径(用于通过 socat 管理 HAProxy)
user <用户名> | group <组名>
指定 HAProxy 进程运行的用户和组(非 root 账户,增强安全性),通常为 haproxy。
daemon
以守护进程(后台)模式运行 HAProxy。
maxconn <数值>
全局最大并发连接数(每个进程的最大连接数)。
nbproc <数值>
启动的进程数(默认 1,多核服务器可设置为 CPU 核心数,提高并发处理能力)
cpu-map 1 0 #指定第一个work绑定第一个cpu核心
cpu-map 2 1 #指定第二个work绑定第二个cpu核心
nbthread <数值>
指定haproxy的线程数量,默认每个进程一个线程
注意:总线程数建议不超过 CPU 核心数(或略高),避免线程切换开销过大(例如 8 核 CPU 可设为
nbproc 2 + nbthread 4
,总线程 8)。
maxsslconn <数值>
每个haproxy进程ssl最大连接数,用于haproxy配置了证书的场景下
maxconnrate <数值>
指定每个客户端每秒建立连接的最大数量
2.defaults -默认配置
定义前端(frontend
)和后端(backend
)的默认参数,可被后续配置继承,减少重复设置。
mode <模式>
haproxy使用的来连接协议
负载均衡模式:http(七层,基于 HTTP 协议)或 tcp(四层,基于 TCP 协议)。
option httplog
日志记录选项,httplog表示记录与 HTTP会话相关的各种属性值
包括 HTTP请求、会话状态、连接数、源地址以及连接时间等
option dontlognull
不记录空会话连接日志(如健康检查的空请求,减少日志冗余)。
option http-server-close
等待客户端完整HTTP请求的时间,此处为等待10s。
option forwardfor
仅
mode http
有效,在 HTTP 头中添加X-Forwarded-For
字段,传递客户端真实 IP 给后端服务器。
option redispatch
当server Id对应的服务器挂掉后,强制定向到其他健康的服务器,重新派发
option http-keep-alive
开启与客户端的会话保持
retries <次数>
连接后端服务器失败次数
timeout connect <时间>
设置等待服务器连接成功的时间
timeout client <时间>
设置服务器超时时间,即允许服务器处于既不接收也不发送数据的非活动时间(例如 50000 表示 50 秒,或者直接写50s)。
timeout server <时间>
设置服务器超时时间,即允许服务器处于既不接收也不发送数据的非活动时间
timeout http-keep-alive <时间>
session 会话保持超时时间,此时间段内会转发到相同的后端服务器
timeout check <时间>
指定后端服务器健康检查的超时时间
errorfile <状态码> <文件路径>
自定义 HTTP 错误页面(例如 errorfile 503 /etc/haproxy/errors/503.http 表示 503 错误时返回指定页面)。
3.frontend-前端配置
定义监听的端口、协议及请求转发规则(接收客户端请求的入口)。
bind <地址:端口>
监听的 IP 地址和端口(*:80 表示监听所有 IP 的 80 端口;192.168.1.1:443 表示指定 IP 的 443 端口)。
mode <模式>
同 defaults,可覆盖默认模式(例如前端同时处理 HTTP 和 TCP 时需单独指定)。
acl <名称> <条件>
定义访问控制列表(ACL)
use_backend <后端名称> if <acl名称>
当 ACL 条件满足时,将请求转发到指定后端(例如 use_backend static_servers if url_static)。
default_backend <后端名称>
当所有 ACL 条件不匹配时,默认转发的后端。
4.default-后端配置
定义负载均衡的后端服务器集群及转发规则(处理前端转发的请求)。
mode <模式>
需与前端对应(http 或 tcp),否则可能导致协议不兼容。
balance <算法> 负载均衡算法(核心参数):
设置负载均衡算法(核心参数),默认roundrobin
server <名称> < IP:端口> [参数]
定义后端服务器
参数:
- check:启用健康检查;
- inter <时间>:健康检查间隔(例如 inter 2000 表示 2 秒)
- rise <次数>:连续健康检查成功 <次数> 后,服务器从下线状态恢复(默认2)
- fall <次数>:连续健康检查失败 <次数> 后,服务器标记为下线(默认3)
- weight <权重>:服务器权重(默认为1,最大值为256,0表示不参与负载均衡,但仍接受持久连接)
- backup:标记为备用服务器(仅当主服务器全部下线时启用),例如sorry server
- disabled :将后端服务器标记为不可用状态,即维护状态
redirect <规则>
将请求临时(302)重定向至其它URL,只适用于http模式
frontend+default示例配置
frontend webcluster_80 bind *:80 #监听服务器上所有网络接口(*)的 80 端口,即接收来自任意 IP 的 HTTP 请求。mode http #工作在七层(应用层)HTTP 模式,支持解析 HTTP 协议内容use_backend webserver #无条件将所有接收到的请求转发到名为 webserver 的后端服务器集群
backend webserverbalance roundrobin #算法:轮询server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
#定义后端服务器 web1:
#192.168.60.10:80 服务器的 IP 和端口;
#check:启用健康检查(定期检测服务器是否可用);
#inter 3s:健康检查间隔为 3 秒;
#fall 3:连续 3 次检查失败,标记服务器为 “下线”(不再分配请求);
#rise 2:连续 2 次检查成功,标记服务器为 “上线”(恢复分配请求);
# weight 2:权重为 2(权重越高,分配的请求比例越大,默认权重为 1)。server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup
#定义 备用服务器 error:
#192.168.60.30:8080:备用服务器的 IP 和端口(端口为 8080,与主服务器不同);
#backup:标记为备用机,仅当所有主服务器(web1、web2)都下线时才启用(用于故障兜底,如返回维护页面)。
listen简化配置
使用listen替换 frontend和backend的配置方式,可以简化设置,通常只用于TCP协议的应用
#下方配置与上方示例配置实现效果完全相同
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup
五、热更新工具(socat)
socat
是一款功能强大的网络工具,全称为 Socket Cat,主要用于在两个数据流向之间建立连接并转发数据。它支持多种协议和数据类型,灵活度极高,常用于网络调试、端口转发、数据转换等场景。
socat
的核心是在 两个地址(address) 之间建立双向通信,实现数据的实时转发。这两个地址可以是:
- 网络端口(TCP/UDP)
- 文件
- 管道(pipe)
- 设备(如串口
/dev/ttyUSB0
) - 标准输入输出(
stdin/stdout
) - 进程(通过命令执行)
可以将socat和haproxy相结合以实现haproxy服务的热更新等复杂功能,使用socat修改haproxy配置,无需重启即可使配置生效
1.安装
dnf install socat-1.7.4.1-5.el9.x86_64 -y
2.haproxy
vim /etc/haproxy/haproxy.cfg
#写入
stats socket /var/lib/haproxy/stats mode 600 level admin
#stats socket:声明一个统计套接字,用于进程间通信(IPC)。
#/var/lib/haproxy/stats:套接字文件的路径,HAProxy 会在启动时创建此文件。
#mode 600:设置套接字文件的权限为 rw-------,即只有文件所有者可以读写,增强安全性。
#level admin:授予最高权限(admin 级别),允许执行所有管理命令。
3…查看haproxy帮助
可以看到详细操作方法
echo "help" | socat stdio /var/lib/haproxy/stats
4.查看haproxy状态
echo "show info" | socat stdio /var/lib/haproxy/stats
5.查看集群状态
echo "show servers state" | socat stdio /var/lib/haproxy/stats# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
3 webcluster_80 1 web1 192.168.60.10 2 0 2 2 770 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 770 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 770 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
...
字段名 | 含义 |
---|---|
be_id | 后端(Backend)的唯一数字标识符 |
be_name | 后端的名称 |
srv_id | 服务器在后端中的唯一数字标识符 |
srv_name | 服务器的名称 |
srv_addr | 服务器的 IP 地址或主机名 |
srv_op_state | 服务器的运行状态(数字编码) |
srv_admin_state | 服务器的管理状态 |
srv_uweight | 用户配置的服务器权重 |
srv_iweight | 服务器的初始权重(基于健康检查动态调整前的权重) |
srv_time_since_last_change | 自上次状态变更以来的时间(毫秒) |
srv_check_status | 最近一次健康检查的状态 |
srv_check_result | 健康检查的详细结果 |
srv_check_health | 健康状态(成功 / 失败次数) |
srv_check_state | 健康检查的当前阶段 |
srv_agent_state | 代理检查状态(如果启用了 agent 检查) |
bk_f_forced_id | 后端强制状态的 ID(用于故障转移) |
srv_f_forced_id | 服务器强制状态的 ID |
srv_fqdn | 服务器的完全限定域名 |
srv_port | 服务器端口号 |
srvrecord | 服务器记录(内部使用) |
srv_use_ssl | 是否使用 SSL 连接到服务器 |
srv_check_port | 健康检查使用的端口 |
srv_check_addr | 健康检查使用的 IP 地址 |
srv_agent_addr | 代理检查的地址 |
srv_agent_port | 代理检查的端口 |
6.查看集群权重
echo "get weight webcluster_80/web1" | socat stdio /var/lib/haproxy/stats
2 (initial 2)echo "get weight webcluster_80/web2" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
7.设置集群服务权重
#设置web1权重为1
echo "set weight webcluster_80/web1 1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "get weight webcluster_80/web1" | socat stdio /var/lib/haproxy/stats
1 (initial 2)#权重为1(之前是2)
8.下线后端服务器
echo "disable server webserver_80/web1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "show servers state" | socat stdio /var/lib/haproxy/stats
... #srv_op_state=0 (DOWN)服务器已宕机,不接收流量
3 webcluster_80 1 web1 192.168.60.10 0 1 1 2 14 6 3 0 14 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 1909 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 1909 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
...srv_op_state 服务器运行状态
0 DOWN 服务器已宕机,不接收流量(健康检查失败或手动禁用)。
1 UP 服务器正常运行,但权重为 0(不参与负载均衡)。
2 UP 服务器正常运行,可接收流量(默认状态)。
3 MAINT 服务器处于维护模式(手动禁用),不接收新流量,但保留现有连接。
4 MAINT(via) 服务器通过上层对象(如后端)继承维护模式。
5 UP (q) 服务器正常,但处于排队状态(等待连接数下降到阈值以下)。
6 DRAIN 服务器处于排水模式(只处理现有连接,不接收新连接)。
7 UP (fv) 服务器正常,但因前端故障(如 SSL 错误)暂时不可用。
8 MAINT (fv) 服务器因前端故障处于维护模式。
9 UP (bck) 服务器正常,但仅作为备份服务器(主服务器全部不可用时启用)。
10 MAINT (bck) 备份服务器处于维护模式。
11 UP (chk) 服务器正常,但正在进行初始健康检查(尚未确认状态)。
12 MAINT (chk) 服务器在维护模式下进行健康检查。
13 UP (nolb) 服务器正常,但被标记为不参与负载均衡(nolb 选项)。
14 MAINT (nolb) 不参与负载均衡的服务器处于维护模式。
9.上线后端服务器
echo "enable server webcluster_80/web1 " | socat stdio /var/lib/haproxy/stats
#查看
echo "show servers state" | socat stdio /var/lib/haproxy/stats#srv_op_state=2 (UP)服务器正常运行,可接收流量量
3 webcluster_80 1 web1 192.168.60.10 2 0 1 2 200 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 2 web2 192.168.60.20 2 0 1 1 2300 6 3 4 6 0 0 0 - 80 - 0 0 - - 0
3 webcluster_80 3 error 192.168.60.30 2 0 1 1 2300 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
六、haproxy状态页
1.配置
vim /etc/haproxy/haproxy.cfg
#写入
listen stats:mode httpbind *:9999log global #使用全局日志stats uri /stats #状态页面的访问路径为 http://IP:9999/statsstats refresh 1s #自动刷新间隔1sstats auth dll:dll #认证 账号:dll 密码:dll
2.访问
3.信息
类别 | 子项 | 说明 |
---|---|---|
session rate(每秒的连接会话信息) | cur | 每秒的当前会话数量 |
max | 每秒新的最大会话数量 | |
limit | 每秒新的会话限制量 | |
sessions(会话信息) | cur | 当前会话量 |
max | 最大会话量 | |
limit | 限制会话量 | |
Total | 总共会话量 | |
LBTot | 选中一台服务器所用的总时间 | |
Last | 和服务器的持续连接时间 | |
Bytes(流量统计) | In | 网络的字节输入总量 |
Out | 网络的字节输出总量 | |
Denied(拒绝统计信息) | Req | 拒绝请求量 |
Resp | 拒绝回复量 | |
Errors(错误统计信息) | Req | 错误请求量 |
conn | 错误链接量 | |
Resp | 错误响应量 | |
Warnings(警告统计信息) | Retr | 重新尝试次数 |
Redis | 再次发送次数 | |
Server (real server 信息) | Status | 后端机的状态,包括 UP 和 DOWN |
LastChk | 持续检查后端服务器的时间 | |
Wght | 权重 | |
Act | 活动链接数量 | |
Bck | 备份的服务器数量 | |
Chk | 心跳检测时间 | |
Dwn | 后端服务器连接后都是 DOWN 的数量 | |
Dwntme | 总的 downtime 时间 | |
Thrtle | server 状态 |
七、haproxy算法
静态算法
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1,不支持其它值),只能靠重启HAProxy生效。
static-rr
按顺序循环分发请求,不考虑服务器实时负载
- 不支持运行时利用socat进行权重的动态调整(只支持0和1,不支持其它值)
- 不支持端服务器慢启动
- 其后端主机数量没有限制,相当于LVS中的 wrr
慢启动是指在服务器刚刚启动上不会把他所应该承担的访问压力全部给它,而是先给一部分,当没
问题后在给一部分
实例配置
listen webcluster_80bind *:80mode httpbalance static-rrserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1server error 192.168.60.30:8080 backup[root@ceshi ~]# for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
first
根据服务器在列表中的位置,自上而下进行调度,当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
- 其会忽略服务器的权重设置
- 不支持用socat进行动态修改权重,可以设置0和1,可以设置其它值但无效
#仅修改算法
...balance first
...
#访问效果
while true;do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs11-192.168.60.10
rs11-192.168.60.10
...
#连续访问,但是rs1跑不满,所以一直访问rs1
动态算法
roundroubin
默认调度算法,使用极为广泛,基于权重动态轮询
- 支持权重的运行时调整,不同于lvs中的rr轮训模式
- HAProxy中的roundrobin支持慢启动
- 其每个后端backend中最多支持4095个real server
- 支持对real server权重动态调整
#仅修改算法为roundroubin
...balance roundrobin
...
for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
leastconn
当前后端服务器加权连接最少的优先调度。
优先选择当前连接数最少且可用的服务器,权重仅在连接数相同的服务器中生效。
- 比较适合长连接的场景使用,比如:MySQL等场景。
- 支持动态调整权重
- 支持慢启动
...balance leastconn
...
#连接数最少的优先访问
for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
rs11-192.168.60.10
rs22-192.168.60.20
其他算法
其它算法即可作为静态算法,也可以通过选项成为动态算法
source
源地址hash,基于⽤户源地址hash并将请求转发到后端服务器。后续同一个源地址请求将被转发至同一个后端web服务器。
适用于需要会话保持,但又不支持cookie和缓存的场景
缺点:
map-base取模法
默认,取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请
求转发至对应的后端服务器。
基于权重取模,hash(source_ip)%所有后端服务器相加的总权重
- 静态方法,不支持socat调整、慢启动
- 当服务器总权重变化时(服务器宕机、开启),会导致调度结果整体变化
例如,后端有三台服务器,每台服务器权重都为1,则总权重为3,haproxy给源地址做hash计算,hash_value%3。其中获取的值如果为0,发给第一台服务器;如果为1,发给第二台服务器;如果为2,发给第三台服务器。如果一台服务器坏掉了,其要在通过hash_value%3计算,因权重发⽣变化⽽导致调度结果整体改变。
配置
listen webcluster_80bind *:80mode httpbalance sourceserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
#测试 同ip访问调度至同一后端服务器
[root@ceshi ~]# for n in {1..10};do curl 192.168.60.30;done
rs11-192.168.60.10
rs11-192.168.60.10
...
[root@test1 ~]# for n in {1..10};do curl 192.168.60.30;done
rs22-192.168.60.20
rs22-192.168.60.20
...
一致性hash
-
一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动
-
支持慢启动,socat热更新
算法解释
1、后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)
2、客户机哈希环点key1=hash(client_ip)%(2^32) 得到的值在[0—4294967295]之间,
3、将keyA和key1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
如图左
将三台服务器ip通过运算得到Key A、Key B、Key C,放到对应位置,客户端ip同理进行运算,放到对应位置
让每个客户端调度至距离最近的服务器,得到
object1—A
object2—B
object3—C
object4—C
注意这里看起来好像是object1距离C更近,但是object1还是调度至A上,为什么——哈希环是一条的单行道,只能顺时针选择最近的单位,禁止逆行。object2、object4同理如图右
当服务器B宕机后,原本调度至B的object4顺时针选择,调度至C上
一致性hash算法可以保证当后端环境变化时,影响最小,某台服务器宕机只会影响本台服务器客户,不像map-base,某台服务器宕机后会导致服务器总权重变化,调度结果整体变化
配置
listen webcluster_80bind *:80mode httpbalance sourcehash-type consistent server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
uri
根据用户请求的 URI 左半部分或整体进行哈希计算,确保相同 URI 的请求被发送到同一台后端服务器。
适用于后端是缓存服务器场景。
默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性
hash
此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
取模法
listen webcluster_80bind *:80mode httpbalance uriserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance urihash-type consistentserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backuprs1写入文件
[root@rs11 /]# echo rs1 index1 > /usr/share/nginx/html/index1.html
[root@rs11 /]# echo rs1 index2 > /usr/share/nginx/html/index2.html
[root@rs11 /]# echo rs1 index3 > /usr/share/nginx/html/index3.html[root@rs22 ~]# echo rs2 index1 > /usr/share/nginx/html/index1.html
[root@rs22 ~]# echo rs2 index2 > /usr/share/nginx/html/index2.html
[root@rs22 ~]# echo rs2 index3 > /usr/share/nginx/html/index3.html测试
[root@ceshi ~]# curl 192.168.60.30/index1.html
rs1 index1
[root@ceshi ~]# curl 192.168.60.30/index2.html
rs1 index2
[root@ceshi ~]# curl 192.168.60.30/index3.html
rs1 index3#使用本地ip测试
[C:\~]$ curl 192.168.60.30/index1.html% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 11 100 11 0 0 697 0 --:--:-- --:--:-- --:--:-- 733
rs2 index1
[C:\~]$ curl 192.168.60.30/index2.html
...
rs2 index2
[C:\~]$ curl 192.168.60.30/index3.html
...
rs2 index3
url_param
对用户请求的url中的 params 部分中的一个参数key对应的value值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server
如果无没key,将按roundrobin算法
取模法
listen webcluster_80bind *:80mode httpbalance url_param nameserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 check server error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance url_param namehash-type consistentserver web1 192.168.60.10:80 check server web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
#测试 参数一致调度至同一个服务器
[root@ceshi ~]# curl 192.168.60.30/index.html?name=6hj3
rs11-192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/index.html?name=123
rs22-192.168.60.20
[root@ceshi ~]# curl 192.168.60.30/index.html?name=*90k
rs11-192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/index.html?name=6hj3
rs11-192.168.60.10
hdr
根据 HTTP 请求头进行哈希计算,确保具有相同请求头的请求被发送到同一台后端服务器。此处由name指定的http首部会被取出并作hash计算。
然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度。
取模法
listen webcluster_80bind *:80mode httpbalance hdr(User-Agent)server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup
一致性hash
listen webcluster_80bind *:80mode httpbalance hdr(User-Agent) #根据浏览器型号hash-type consistentserver web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4server error 192.168.60.30:8080 backup#测试
curl -v 192.168.60.30
* Trying 192.168.60.30:80...
* Connected to 192.168.60.30 (192.168.60.30) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.60.30
> User-Agent: curl/7.76.1 #这次访问方式为curl
> Accept: */*
...
rs22-192.168.60.20
#使用edge测试
[root@ceshi ~]# curl -vA edge 192.168.60.30
rs22-192.168.60.20
#火狐
[root@ceshi ~]# curl -A firefox 192.168.60.30
rs11-192.168.60.10
#谷歌
[root@ceshi ~]# curl -A Google 192.168.60.30
rs22-192.168.60.20
#使用相同的浏览器会调度至相同服务器
[root@ceshi ~]# curl -A Google 192.168.60.30
rs22-192.168.60.20
[root@ceshi ~]# curl -A firefox 192.168.60.30
rs11-192.168.60.10
八、基于cookie的会话保持
为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于 source 地址hash调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
不支持 tcp mode
配置
listen webcluster_80bind *:80mode httpbalance roundrobincookie WEBCOOKIE insert nocache indirect
##name: cookie 的 key名称,用于实现持久连接
#insert: 插入新的cookie,默认不插入cookie
#indirect: 如果客户端已经有cookie,则不会再发送cookie信息
#nocache: 当client和hapoxy之间有缓存服务器(如:CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器server web1 192.168.60.10:80 check cookie web1 #指定cookie为web1server web2 192.168.60.20:80 check cookie web2server error 192.168.60.30:8080 backup
浏览器中F12查看详细信息
测试
#指定cookie访问
[root@ceshi ~]# curl -b WEBCOOKIE=web1 192.168.60.30
rs11-192.168.60.10
[root@ceshi ~]# curl -b WEBCOOKIE=web1 192.168.60.30
rs11-192.168.60.10
[root@ceshi ~]# curl -b WEBCOOKIE=web2 192.168.60.30
rs22-192.168.60.20
九、IP透传
四层
haproxy
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check send-proxyserver web2 192.168.60.20:80 check send-proxyserver error 192.168.60.30:8080 backup
nginx
http {log_format main '$remote_addr - $remote_user [$time_local] "$request" '' "$proxy_protocol_addr"'#记录透传过来的ip'$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
...server {listen 80 proxy_protocol; ##启用此项,将无法直接访问此网站,只能通过四层代理访问listen [::]:80;server_name _;root /usr/share/nginx/html;
查看日志
[root@rs11 html]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:20:47:19 +0800] "GET / HTTP/1.1" "192.168.60.66"200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:20:47:27 +0800] "GET / HTTP/1.1" "192.168.60.66"200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:20:47:50 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
192.168.60.30 - - [23/Jul/2025:20:47:52 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
192.168.60.30 - - [23/Jul/2025:20:47:53 +0800] "GET / HTTP/1.1" "192.168.60.88"200 19 "-" "curl/7.76.1" "192.168.60.88"
七层
haproxy
listen webcluster_80bind *:80mode httpbalance roundrobinoption forwardfor #开启IP透传server web1 192.168.60.10:80 checkserver web2 192.168.60.20:80 checkserver error 192.168.60.30:8080 backup
nginx
http {log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
查看日志
[root@rs11 html]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:20:59:26 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:14 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:15 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
[root@rs22 ~]# tail -n 5 /var/log/nginx/access.log
192.168.60.30 - - [23/Jul/2025:21:03:12 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:13 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:14 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:15 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
192.168.60.30 - - [23/Jul/2025:21:03:16 +0800] "GET / HTTP/1.1" 200 19 "-" "curl/7.76.1" "192.168.60.66"
十、ACL
ACL(Access Control List)是一种强大的条件判断机制,用于基于 HTTP 请求、响应或 TCP 连接的属性(如 URL、请求头、客户端 IP 等)进行匹配,从而实现灵活的流量控制、请求路由和负载均衡决策。
- 流量过滤:允许或拒绝特定类型的请求(如封禁恶意 IP)。
- 请求路由:根据条件将请求转发到不同的后端服务器组(如移动端请求路由到专用后端)。
ACL配置选项
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
名称
可以使用大字母A-Z、小写字母a-z、数字0-9、冒号:、点.、中横线和下划线,严格区分大小写
ACL-criterion 匹配规范
1.head
[root@test1 ~]# curl -v 192.168.60.30
* Trying 192.168.60.30:80...
* Connected to 192.168.60.30 (192.168.60.30) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.60.30
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: nginx/1.20.1
< date: Sat, 26 Jul 2025 10:28:31 GMT
< content-type: text/html
< content-length: 19
< last-modified: Thu, 17 Jul 2025 08:06:05 GMT
< etag: "6878aeed-13"
< accept-ranges: bytes
<
rs11-192.168.60.10
* Connection #0 to host 192.168.60.30 left intact
hdr:用于完全匹配 HTTP 请求报文首部的指定字符串,格式为hdr(<name> (,<occ>))
,<name>
是 header 的指定信息,<occ>
表示在多值中使用的值的出现次数。
acl is_google hdr(host) -i www # 匹配Host头为"www"的请求 -i忽略大小写
hdr_beg:前缀匹配,即匹配 header 中指定内容的开头,格式为hdr_beg(<name> (,<occ>))
。
acl is_api hdr_beg(path) /api # 匹配路径以/api开头的内容
hdr_end:后缀匹配,匹配 header 中指定内容的结尾,格式为hdr_end(<name> (,<occ>))
。
acl is_js hdr_end(path) .img # 匹配路径以.img结尾的请求
hdr_dom:域匹配,用于匹配 header 中的域名,格式为hdr_dom(<name> (,<occ>))
。
acl pc_web_page hdr_dom(host) -i www.badidu.com # 匹配所有请求域名为www.badidu.com的请求
hdr_dir:路径匹配,匹配 header 的 uri 路径,格式为hdr_dir(<name> (,<occ>))
。
acl in_images hdr_dir(path) /images # 匹配路径包含"/images"目录的请求
hdr_len:长度匹配,匹配 header 的长度,格式为hdr_len(<name> (,<occ>))
。
acl long_cookie hdr_len(cookie) gt 500 # 匹配Cookie长度超过500的请求
hdr_reg:正则表达式匹配,使用自定义表达式 (regex) 进行模糊匹配,格式为hdr_reg(<name> (,<occ>))
。
acl ie6 hdr_reg(User-Agent) -i MSIE\ [1-6]\. #匹配IE1-6
hdr_sub:子串匹配,在 header 中的 uri 进行模糊匹配,格式为hdr_sub(<name> (,<occ>))
。
acl has_token hdr_sub(authorization) Bearer # 匹配Authorization头包含"Bearer"的请求
2.base:string
返回第一个主机头和请求的路径部分的连接,该请求从主机名host开始,并在问号之前结束,对虚拟主机有用
😕/:@:/
匹配类型 | 描述 |
---|---|
base | 精确字符串匹配 |
base_beg | 前缀匹配 |
base_dir | 子目录匹配 |
base_dom | 域名匹配 |
base_end | 后缀匹配 |
base_len | 长度匹配 |
base_reg | 正则表达式匹配 |
base_sub | 子字符串匹配 |
3.path : string
提取请求的URL路径,该路径从/
😕/:@:/
匹配类型 | 描述 |
---|---|
path | 精确字符串匹配 |
path_beg | 前缀匹配(请求的 URL 开头,如 /static、/images、/img、/css) |
path_end | 后缀匹配(请求的 URL 中资源的结尾,如 .gif、.png、.css、.js、.jpg、.jpeg) |
path_dom | 域名匹配 |
path_dir | 子目录匹配 |
path_len | 长度匹配 |
path_reg | 正则表达式匹配 |
path_sub | 子字符串匹配 |
4.src | dst
匹配类型 | 描述 |
---|---|
src | 匹配源 IP 地址或网段。 |
src_port | 匹配源端口。 |
dst | 匹配目标 IP 地址(通常是负载均衡器的 IP)。 |
dst_port | 匹配目标端口。 |
ACL-flags 匹配模式
ACL匹配模式
-i 不区分大小写
-m 指定正则的匹配方法
-n 不做DNS解析
-u 禁止acl重名,否则多个同名ACL匹配或关
ACL-operator 具体操作符
整数操作符
操作符 含义
eq 等于
ne 不等于
gt 大于
ge 大于等于
lt 小于
le 小于等于
字串匹配
-m str 完全匹配字符串 字符串必须完全匹配模式
-m sub 包含子串 在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
-m beg 前缀匹配 在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
-m end 后缀匹配 将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配
-m dir 路径目录匹配 查看提取出来的用斜线分隔(“/”)的字符串,如其中任一个匹配,则ACL进行匹配
-m dom 域名或子域名匹配 查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进行匹配
组合使用
与:隐式(默认)使用
或:使用“or" 或 “||"表示
否定:使用 “!” 表示
示例
if valid_src valid_port #与关系,ACL中A和B都要满足为true,默认为与
if invalid_src || invalid_port #或,ACL中A或者B满足一个为true
if ! invalid_src #非,取反,不满足ACL才为true
示例
1.域名匹配
配置
frontend webcluster_80bind *:80mode http
#acl
acl web_host hdr_dom(host) www.dl.org
#host
use_backend webserver1 if web_host
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
测试
#地址解析
[root@test1 ~]# cat /etc/hosts
...
192.168.60.30 www.dl.org[root@test1 ~]# curl www.dl.org
rs11-192.168.60.10
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl www.dl.org
rs11-192.168.60.10
IP控制
配置
frontend webcluster_80bind *:80mode http
#acl
acl ip_test src 192.168.60.1
acl web_host hdr_dom(host) www.dl.org#host
use_backend webserver1 if ip_test
http-request deny if web_host#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
测试
#192.168.60.1
[C:\~]$ curl 192.168.60.30% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 19 100 19 0 0 8543 0 --:--:-- --:--:-- --:--:-- 9500
rs11-192.168.60.10
#192.168.60.88
[root@test1 ~]# curl 192.168.60.30
rs22-192.168.60.20
[root@test1 ~]# curl www.dl.org
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
#192.168.60.66
[root@ceshi ~]# curl 192.168.60.30
rs22-192.168.60.20
匹配浏览器类型
frontend webcluster_80bind *:80mode http
#acl
acl user_agent_block hdr_sub(User-Agent) -i curl wget #匹配 curl wget
acl user_agent_redirect hdr_sub(User-Agent) -i Mozilla/5.0 #匹配所有类型浏览器#host
http-request deny if user_agent_block #拒绝curl wget
redirect prefix https://www.baidu.com if user_agent_redirect #将所有浏览器请求重定向至百度
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
测试
[root@test1 ~]# curl 192.168.60.30
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@test1 ~]# wget 192.168.60.30
--2025-07-26 20:06:06-- http://192.168.60.30/
Connecting to 192.168.60.30:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2025-07-26 20:06:06 ERROR 403: Forbidden.
基于后缀动静分离
配置
frontend webcluster_80bind *:80mode http
#acl
acl url_static path_end -i .jpg .png .css .js .html
acl url_php path_end -i .php#host
use_backend webserver1 if url_static
use_backend webserver2 if url_php
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
测试
[root@ceshi ~]# curl 192.168.60.30/index.php
php 192.168.60.20
[root@ceshi ~]# curl 192.168.60.30/index.css
css 192.168.60.10
[root@ceshi ~]#
基于路径实现动静分离
frontend webcluster_80bind *:80mode http
#acl
acl url_static path_end -m sub /static /images /javascript
acl acl_app path_beg -m sub /api
#host
use_backend webserver1 if url_static
use_backend webserver2 if acl_app
#default
default_backend webserver2backend webserver1balance roundrobinserver web1 192.168.60.10:80 checkbackend webserver2server web2 192.168.60.20:80 check
测试
[root@ceshi ~]# curl 192.168.60.30/static/
static 192.168.60.10
[root@ceshi ~]# curl 192.168.60.30/api/
api 192.168.60.20
十一、自定义错误页面
haproxy默认使用的错误错误页面
[root@haproxy ~]# rpm -ql haproxy | grep -E http$
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http
自定义错误页面
#打开配置文件写入
vim /etc/haproxy/haproxy.cfg
errorfile 503 /haproxy/errorpages/503page.http#创建目录
mkdir /haproxy/errorpages/ -p
#复制文件
cp /usr/share/haproxy/503.http /haproxy/errorpages/503page.http
#修改
vim /haproxy/errorpages/503page.http
HTTP/1.0 503 Service Unavailable^M
Cache-Control: no-cache^M
Connection: close^M
Content-Type: text/html^M
^M
<html><body><h1>服务器也需要休息</h1>
请稍后访问
</body></html>
#重启haproxy服务
systemctl restart haproxy.service
测试
#关闭后端服务器
listen webcluster_80bind *:80mode httpbalance roundrobinserver web1 192.168.60.10:80 check disabledserver web2 192.168.60.20:80 check disabled# server error 192.168.60.30:8080 backup
#访问
[root@test1 ~]# curl 192.168.60.30
<html><body><h1>服务器也需要休息</h1>
请稍后访问
</body></html>
错误页面重定向
#打开配置文件写入
vim /etc/haproxy/haproxy.cfg
errorloc 503 https://www.163.com
十二、四层负载示例
这里以数据库为例
haproxy
vim /etc/haproxy/haproxy.conf
listen webcluster_80bind *:3306mode tcpbalance roundrobinserver web1 192.168.60.10:3306 checkserver web2 192.168.60.20:3306 check
rs1
#安装数据库
dnf install mariadb-server -y
#启动
systemctl start mariadb
#添加用户
mysql -e "grant all on *.* to dll@'%' identified by 'dll';"
rs2
yum install mariadb-server -y
systemctl start mariadb
mysql -e "grant all on *.* to dll@'%' identified by 'dll';"
测试
[root@ceshi ~]# mysql -udll -pdll -h 192.168.60.30 -e "show variables like'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs11 |
+---------------+-------+
[root@ceshi ~]# mysql -udll -pdll -h 192.168.60.30 -e "show variables like'hostname'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rs22 |
+---------------+-------+
https实现
证书制作
#创建目录
mkdir /etc/haproxy/certs/
#制作证书
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/dl.key -x509 -days 365 -out /etc/haproxy/certs/dl.crt
#制作.pem文件
cat dl.key dl.crt >dl.pem
haproxy配置
frontend webserverbind *:80redirect scheme https if !{ ssl_fc } #全站加密#redirect scheme https:将请求的协议从 HTTP 重定向为 HTTPS。#if !{ ssl_fc }:条件判断,! 表示否定,{ ssl_fc } 检查当前连接是否使用 SSL/TLS。#即:仅对非 HTTPS 请求执行重定向。mode httpuse_backend webclusterfrontend webserver-httpsbind *:443 ssl crt /etc/haproxy/certs/dl.pem #指定证书文件mode httpuse_backend webclusterbackend webclustermode httpbalance roundrobinserver web1 192.168.60.10:80 checkserver web2 192.168.60.20:80 check
测试
[root@test1 ~]# curl -k https://192.168.60.30
php 192.168.60.20
[root@test1 ~]# curl -k https://192.168.60.30
rs11-192.168.60.10