haproxy原理及实战部署

发布于:2025-07-27 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、负载均衡

负载均衡是网络架构和分布式系统中至关重要的技术,其核心作用是将大量的并发请求或数据流量合理分配到多个服务器(或其他资源节点)上,从而解决单节点压力过大、资源利用率低、系统稳定性差等问题。

作用

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 webserver
        balance 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 1
        server 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_80
        bind    *:80
        mode    http
        balance roundrobin
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1
        server 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 http
        bind *:9999
        log global		 #使用全局日志
        stats uri /stats  #状态页面的访问路径为 http://IP:9999/stats
        stats refresh 1s  #自动刷新间隔1s
        stats 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_80
        bind    *:80
        mode    http
        balance static-rr
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 1
        server 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_80
        bind    *:80
        mode    http
        balance source
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4
        server 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_80
        bind    *:80
        mode    http
        balance source
        hash-type consistent 
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4
        server error 192.168.60.30:8080 backup

uri

根据用户请求的 URI 左半部分或整体进行哈希计算,确保相同 URI 的请求被发送到同一台后端服务器。

适用于后端是缓存服务器场景。

默认是静态算法,也可以通过hash-type指定map-based和consistent,来定义使用取模法还是一致性
hash

此算法基于应用层,所以只支持 mode http ,不支持 mode tcp

取模法

listen  webcluster_80
        bind    *:80
        mode    http
        balance uri
        server 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_80
        bind    *:80
        mode    http
        balance uri
        hash-type consistent
        server web1 192.168.60.10:80 check 
        server web2 192.168.60.20:80 check
        server error 192.168.60.30:8080 backup

rs1写入文件
[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  Current
                                 Dload  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_80
        bind    *:80
        mode    http
        balance url_param name
        server 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_80
        bind    *:80
        mode    http
        balance url_param name
        hash-type consistent
        server web1 192.168.60.10:80 check 
        server web2 192.168.60.20:80 check
        server 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_80
        bind    *:80
        mode    http
        balance hdr(User-Agent)
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4
        server error 192.168.60.30:8080 backup

一致性hash

listen  webcluster_80
        bind    *:80
        mode    http
        balance hdr(User-Agent) #根据浏览器型号
        hash-type consistent
        server web1 192.168.60.10:80 check inter 3s fall 3 rise 2 weight 2
        server web2 192.168.60.20:80 check inter 3s fall 3 rise 2 weight 4
        server 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_80
        bind    *:80
        mode    http
        balance roundrobin
        cookie 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为web1
        server web2 192.168.60.20:80 check cookie web2
        server 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_80
        bind    *:80
        mode    http
        balance roundrobin

        server web1 192.168.60.10:80 check send-proxy
        server web2 192.168.60.20:80 check send-proxy
        server 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_80
        bind    *:80
        mode    http
        balance roundrobin
        option forwardfor #开启IP透传
        server web1 192.168.60.10:80 check
        server web2 192.168.60.20:80 check
        server 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_80
        bind    *:80
        mode    http
#acl
acl web_host hdr_dom(host) www.dl.org
#host
use_backend webserver1 if web_host
#default
default_backend webserver2

backend webserver1
        balance roundrobin
        server web1 192.168.60.10:80 check

backend webserver2
        server 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_80
        bind    *:80
        mode    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 webserver2

backend webserver1
        balance roundrobin
        server web1 192.168.60.10:80 check

backend webserver2
        server 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  Current
                                 Dload  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_80
        bind    *:80
        mode    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 webserver2

backend webserver1
        balance roundrobin
        server web1 192.168.60.10:80 check

backend webserver2
        server 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_80
        bind    *:80
        mode    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 webserver2

backend webserver1
        balance roundrobin
        server web1 192.168.60.10:80 check

backend webserver2
        server 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_80
        bind    *:80
        mode    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 webserver2

backend webserver1
        balance roundrobin
        server web1 192.168.60.10:80 check

backend webserver2
        server 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_80
        bind    *:80
        mode    http
        balance roundrobin
        server web1 192.168.60.10:80 check disabled
        server 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_80
        bind    *:3306
        mode    tcp
        balance roundrobin
        server web1 192.168.60.10:3306 check
        server 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 webserver
        bind *:80
        redirect scheme https if !{ ssl_fc }  #全站加密
        #redirect scheme https:将请求的协议从 HTTP 重定向为 HTTPS。
		#if !{ ssl_fc }:条件判断,! 表示否定,{ ssl_fc } 检查当前连接是否使用 SSL/TLS。
		#即:仅对非 HTTPS 请求执行重定向。
        mode http
        use_backend webcluster

frontend webserver-https
        bind *:443 ssl crt /etc/haproxy/certs/dl.pem  #指定证书文件
        mode http
        use_backend webcluster

backend webcluster
        mode http
        balance roundrobin
        server web1 192.168.60.10:80 check
        server 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


网站公告

今日签到

点亮在社区的每一天
去签到