HAProxy实验搭建

HAProxy实验搭建


HAProxy 介绍

HAProxy 是一款提供高可用性、负载均衡以及基于 TCP(第四层)和 HTTP(第七层)应用的代理软件,支持虚拟主机。它是免费、快速并且可靠的一种解决方案。

HAProxy 特别适用于负载较大的 Web 站点,这些站点通常又需要会话保持或七层处理。HAProxy 运行在当下的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单、安全地整合进您当前的架构中,同时可以保护 Web 服务器不被暴露到网络上。

HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在用户端(User-Space)有更好的资源和时间管理来实现所有这些任务。此模型的弊端是,在多核系统上,这些程序通常扩展性较差,因此必须进行优化以使每个 CPU 时间片(Cycle)做更多的工作。

性能

HAProxy 借助于 OS 上几种常见的技术来实现性能的最大化:

  1. 单进程、事件驱动模型显著降低了上下文切换的开销及内存占用。
  2. O(1) 事件检查器(event checker)允许其在高并发连接中对任何连接的任何事件实现即时探测。
  3. 在任何可用的情况下,单缓冲(single buffering)机制能以不复制任何数据的方式完成读写操作,这会节约大量的 CPU 时钟周期及内存带宽。
  4. 借助于 Linux 2.6(>= 2.6.27.19)上的 splice() 系统调用,HAProxy 可以实现零复制转发(Zero-copy forwarding);在 Linux 3.5 及以上的 OS 中还可以实现零复制启动(zero-starting)。
  5. 内存分配器在固定大小的内存池中可实现即时内存分配,能够显著减少创建一个会话的时长。
  6. 树型存储:使用弹性二叉树,以 O(log(N)) 的低开销保持计时器、运行队列及管理轮询与最少连接队列。
  7. 优化的 HTTP 首部分析:避免在 HTTP 首部分析过程中重读任何内存区域。
  8. 精心地降低了昂贵的系统调用,大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等。

所有这些细微优化,使 HAProxy 在中等规模负载之上依然有着相当低的 CPU 负载。在非常高的负载场景中,5% 的用户空间占用率和 95% 的系统空间占用率也非常普遍,这意味着 HAProxy 进程消耗比系统空间消耗低 20 倍以上。因此,对 OS 进行性能调优非常重要。即使用户空间的占用率提高一倍,其 CPU 占用率也仅为 10%,这也解释了为何七层处理对性能影响有限。在高端系统上,HAProxy 的七层性能可轻易超过硬件负载均衡设备。

在生产环境中,也常将 HAProxy 作为昂贵的高端硬件负载均衡设备故障时的七层应急方案。硬件负载均衡设备在「报文」级别处理请求,支持跨报文请求(request across multiple packets)难度较高,且不缓冲任何数据,响应时间较长。软件负载均衡设备使用 TCP 缓冲,可建立极长的请求,响应时间相对更灵活。

HAProxy 调度算法

HAProxy 有 8 种负载均衡算法(balance),分别如下:

算法 说明
roundrobin(rr) 动态加权轮询,支持权重
static-rr 静态轮询,不支持权重
leastconn 最小连接优先处理
source 源地址哈希
uri 根据 URI 做哈希
url_param 根据 URL 参数做哈希(需指定参数名)
hdr(name) 根据 HTTP 请求头锁定每一次请求
rdp-cookie(name) 根据 Cookie 锁定并哈希每一次 TCP 请求

HAProxy 实践

通过 HAProxy 实现四层和七层负载均衡。

网络拓扑

主机名 IP 地址 服务器角色
client2.rich.cloud 10.1.1.21 客户端
client1.rich.cloud 10.1.8.21 客户端
router.rich.cloud 10.1.8.20 / 10.1.1.20 路由器
haproxy.rich.cloud 10.1.8.10 / 10.1.1.10 代理服务器
web1.rich.cloud 10.1.8.11 Web 和 SSH 服务器
web2.rich.cloud 10.1.8.12 Web 和 SSH 服务器
web3.rich.cloud 10.1.8.13 Web 和 SSH 服务器

网络说明:

  1. 所有主机:第一块网卡名为 ens33,第二块网卡名为 ens192
  2. 默认第一块网卡模式为 NAT,第二块网卡模式为 Host-Only。
  3. 网关设置:10.1.1.0/24 网段网关为 10.1.1.2010.1.8.0/24 网段网关为 10.1.8.20

基础网络配置

bash 复制代码
# 10.1.1.0/24 网段网关为 10.1.1.20
nmcli connection modify ens33 ipv4.gateway 10.1.1.20
nmcli connection up ens33

# 10.1.8.0/24 网段网关为 10.1.8.20(可以不改)
nmcli connection modify ens33 ipv4.gateway 10.1.8.20
nmcli connection up ens33

配置 router

bash 复制代码
# 设置防火墙
systemctl enable firewalld.service --now
firewall-cmd --set-default-zone=trusted
firewall-cmd --add-masquerade --permanent
firewall-cmd --add-masquerade

# 开启路由
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

HTTP 模式

配置 Web 服务器(web1--web3)

bash 复制代码
# 部署 Web
yum install -y nginx
echo "Welcome to $(hostname)" > /usr/share/nginx/html/index.html
systemctl enable nginx.service --now

访问后端 Nginx:

bash 复制代码
[root@client1 ~]# curl 10.1.8.11
Welcome to web1.rich.cloud

[root@client1 ~]# curl 10.1.8.12
Welcome to web2.rich.cloud

[root@client1 ~]# curl 10.1.8.13
Welcome to web3.rich.cloud

准备虚拟主机:

bash 复制代码
cat > /etc/nginx/conf.d/vhost-test.conf <<'EOF'
server {
    listen 81;
    root /test;
}
EOF

systemctl restart nginx

# 准备测试文件
mkdir /test
echo "hello txt from $(hostname -s)" > /test/index.txt
echo "hello html from $(hostname -s)" > /test/index.html

测试:

bash 复制代码
[root@client1 ~]# curl http://web1:81/
hello html from web1

[root@client1 ~]# curl http://web2:81/
hello html from web2

[root@client1 ~]# curl http://web3:81/
hello html from web3

配置 HAProxy(HTTP)

bash 复制代码
# 安装 HAProxy
yum install -y haproxy

# 备份配置文件
cp /etc/haproxy/haproxy.cfg{,.ori}

# 在配置文件末尾追加以下内容
cat >> /etc/haproxy/haproxy.cfg <<'EOF'

######### web 代理 ###########
frontend front_web
    bind *:80
    default_backend back_web
    # acl:固定关键字;test:规则名,可自定义
    # url_reg:匹配方式;-i:忽略大小写;\.txt$:匹配 .txt 结尾
    acl test url_reg -i \.txt$
    # 若 acl 规则 test 匹配,则使用后端 back_test
    use_backend back_test if test

backend back_web
    balance roundrobin
    # server:关键字,代表后端主机
    # web1:后端主机名,可自定义,建议与主机名一致
    # 10.1.8.11:80:后端实际地址和端口
    # check:HAProxy 检查后端服务是否正常
    server web1 10.1.8.11:80 check
    server web2 10.1.8.12:80 check
    server web3 10.1.8.13:80 check

backend back_test
    balance roundrobin
    server test1 10.1.8.11:81 check
    server test2 10.1.8.12:81 check
    server test3 10.1.8.13:81 check
EOF

# 启用并启动服务
systemctl enable haproxy.service --now

HTTP 模式测试

测试 .txt 结尾的 ACL 规则:

bash 复制代码
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10/index.txt -s; done | sort | uniq -c

[root@client2 ~]# for n in {1..90}; do curl http://10.1.1.10 -s; done | sort | uniq -c
     30 Welcome to web1.rich.cloud
     30 Welcome to web2.rich.cloud
     30 Welcome to web3.rich.cloud

轮询测试(默认后端):

bash 复制代码
[root@client1 ~]# for n in {1..90}; do curl http://10.1.8.10 -s; done | sort | uniq -c
     30 Welcome to web1.rich.cloud
     30 Welcome to web2.rich.cloud
     30 Welcome to web3.rich.cloud

TCP 模式

配置 SSH(web1--web3)

bash 复制代码
yum install -y openssh-server
systemctl enable sshd --now

配置 HAProxy(TCP / SSH)

bash 复制代码
cp /etc/haproxy/haproxy.cfg{,.ori}

cat >> /etc/haproxy/haproxy.cfg <<'EOF'

######### ssh 代理 ###########
listen ssh
    mode tcp
    bind *:1022
    balance roundrobin
    server web1 10.1.8.11:22 check
    server web2 10.1.8.12:22 check
    server web3 10.1.8.13:22 check
EOF

systemctl restart haproxy.service

TCP 模式测试

bash 复制代码
[root@client1 ~]# for n in {1..90}; do ssh root@haproxy -p 1022 hostname 2>/dev/null; done | sort | uniq -c
     30 web1.rich.cloud
     30 web2.rich.cloud
     30 web3.rich.cloud

HAProxy 配置说明

HAProxy 的配置文件由两部分组成:

  • global settings:定义 HAProxy 进程管理、安全及性能相关参数。
  • proxies :对代理的设定,共分为 4 段:
    • defaults :为其它配置段提供默认参数,可由下一个 defaults 重新设定。
    • frontend:定义监听的套接字,接受客户端请求并建立连接。
    • backend:定义后端服务器,前端将请求调度至这些服务器。
    • listen:将 frontend 与 backend 合并,通常用于 TCP(四层)代理。

所有代理的名称只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和 :(冒号)。此外,ACL 名称区分大小写。

全局部分

进程管理及安全相关参数
haproxy 复制代码
# log <address> <facility> [max level [min level]]:定义全局 syslog,最多两个
log 127.0.0.1 local2

# log-send-hostname [<string>]:在 syslog 首部添加主机名
log-send-hostname haproxy.rich.cloud

# chroot:变更工作目录并 chroot,提升安全(目录须为空且不可写)
chroot /var/lib/haproxy

# daemon:以守护进程方式在后台运行
daemon

# pidfile:进程 PID 文件路径
pidfile /var/run/haproxy.pid

# uid / user:以指定 UID 或用户身份运行
uid 188
user haproxy

# gid / group:以指定 GID 或组身份运行
gid 188
group haproxy

# stats socket:启用 Unix socket,用于访问统计数据
stats socket /var/lib/haproxy/stats

# node:当前节点名称(多 HAProxy 共享 IP 时使用)
node ha1.rich.cloud

# description:当前实例描述
description haproxy server 1
性能调整相关参数
haproxy 复制代码
# nbproc <number>:进程个数(仅守护进程模式;调试困难,一般不推荐多进程)
nbproc 2

# ulimit-n:每进程最大文件描述符数(默认自动计算,不推荐修改)
# Linux 默认单进程约 1024

# maxconn <number>:每进程最大并发连接数,等同命令行 -n
maxconn 4000

# tune.bufsize:buffer 大小,默认 16384,强烈建议使用默认值
# tune.chksize:检查缓冲区大小,不建议修改
# tune.maxaccept:一次性可接受连接数,一般不建议修改
# tune.maxpollevents:单次系统调用可处理事件数
# tune.maxrewrite:首部重写预留缓冲,建议约 1024
# tune.rcvbuf.server:内核套接字接收缓冲,强烈推荐默认值

代理部分(defaults 示例)

haproxy 复制代码
# mode:tcp 工作在四层,仅转发;http 工作在七层,可处理请求/响应
mode http

log global
log 127.0.0.1:514 local0 notice

option httplog          # HTTP 日志格式,也可 tcplog
option dontlognull      # 不记录无数据的心跳检测包
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch       # 连接失败后重新分发

retries 3

timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 1m
timeout check 10s

HAProxy 使用总结

HAProxy 是高性能开源负载均衡器,支持 TCP 四层与 HTTP 七层代理,核心功能包括负载策略(轮询、加权、IP 哈希等)、后端健康检查(主动/被动)及会话保持。

通过 frontend / backend / listen 配置块定义转发规则,可实现 SSL 终止、请求过滤与流量控制。轻量且高并发,常用于 Web 服务、数据库等场景的高可用架构;搭配日志监控与故障转移,能有效提升服务稳定性与资源利用率。

相关推荐
青梅橘子皮1 小时前
Linux---开发工具(2)(makefile、进度条、git、gdb)
linux·运维·服务器
剑神一笑1 小时前
Linux less 命令深度解析:从源码看分页器的设计智慧
linux·运维·less
李白你好2 小时前
Linux 本地提权工具支持Linux 内核和 Polkit 漏洞
linux·运维·服务器
陳10302 小时前
Linux:System V IPC
linux·运维·服务器
米高梅狮子2 小时前
01.mysql的备份与恢复
运维·数据库·mysql·docker·容器·kubernetes·github
aFakeProgramer2 小时前
在Ubuntu系统格式化SD卡,单分区/双分区
linux·运维·ubuntu
Hello--_--World2 小时前
利用CDN进行首屏优化。能不能看CDN与本地服务器谁快用谁?
运维·服务器·前端·javascript·vite
云飞云共享云桌面2 小时前
硬件采购省50%、设计效率提40%——通过云飞云共享云桌面一台云主机拖10人的真实跑法
运维·服务器·网络·人工智能·自动化
量子炒饭大师2 小时前
【Linux系统编程】——【从0构建第一个Linux系统-进度条】从0到1分阶段构建动态进度条
linux·运维·服务器·进度条