集群与负载均衡:HAProxy 与 Nginx 实践
高可用和负载均衡
集群
概念
集群 (Cluster):是由多台计算机(节点)通过网络组合在一起,对外表现为一个整体系统。
特点:
高性能:并行计算能力增强。
高可用:某个节点故障,其他节点接管。
可扩展:增加节点即可扩展能力。
类型
常见的集群分为三类:
高性能计算集群(HPC,High Performance Computing)
目标:提高计算能力,适用于科学计算、大数据分析。
特点:任务切分 → 并行执行 → 汇总结果。
高可用集群(HA,High Availability)
目标:保证服务连续运行。
特点:一个节点宕机,另一个自动接管(故障转移)。
应用:数据库集群、关键业务系统。
负载均衡集群(Load Balancing Cluster)
目标:分配请求,避免单点压力。
特点:多个节点同时处理请求,通过调度算法分流。
应用:Web 服务、应用服务器集群。
负载均衡集群
作用:把用户请求合理分发到后端多台服务器,提高并发处理能力和稳定性。
常见负载均衡实现方式:
硬件负载均衡:如 F5、Array,性能高但成本高。
软件负载均衡:常见方案有
Nginx:反向代理 + 负载均衡
HAProxy:专业负载均衡器,支持四层/七层
LVS:Linux Virtual Server,高性能四层负载均衡
HAProxy
简介
一款开源的负载均衡软件,支持 TCP(四层)和 HTTP(七层)代理。
以高性能和高并发著称,广泛应用于互联网企业。
特点
支持四层(TCP)和七层(HTTP)代理。
内置多种负载均衡算法(轮询、最少连接、源地址哈希等)。
高并发性能强,支持数十万连接。
提供健康检查,能自动剔除故障节点。
提供状态统计页面,便于运维监控。
常见负载均衡算法
roundrobin
:轮询,默认方式。leastconn
:最少连接,优先选择连接数少的服务器。source
:根据请求源 IP 分配,保证同一 IP 始终访问同一服务器。
实践
安装
[root@centos7 ~ 10:50:32]# vim /etc/hosts[root@centos7 ~ 10:54:10]# cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6#####cluster#####10.1.8.10 lb.yuxb.cloud lb10.1.8.11 web1.yuxb.cloud web110.1.8.12 web2.yuxb.cloud web210.1.8.13 web3.yuxb.cloud web310.1.8.20 router.yuxb.cloud router10.1.8.21 client1.yuxb.cloud client110.1.1.21 client2.yuxb.cloud client2
lb
添加一块网卡,选vm1sethost 10[root@lb ~ 12:31:52]# nmcli connection modify 7f031843-1f62-3beb-8783-8888d08dc2b8 connection.id ens36 ipv4.method manual ipv4.addresses 10.1.1.10/24[root@lb ~ 12:34:27]# nmcli connection up ens36连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/8)[root@lb ~ 12:34:40]# ip -br alo UNKNOWN 127.0.0.1/8 ::1/128 ens33 UP 10.1.8.10/24 fe80::20c:29ff:fe80:a684/64 ens36 UP 10.1.1.10/24 fe80::ee29:4731:589:aa3c/64
router
和lb一样,也要添加网卡还有上面的操作+# 开启路由[root@router ~ 12:48:57]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf[root@router ~ 12:49:15]# sysctl -pnet.ipv4.ip_forward = 1# 防火墙[root@router ~ 12:49:15]# systemctl enable firewalld.service --nowCreated symlink from /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service to /usr/lib/systemd/system/firewalld.service.Created symlink from /etc/systemd/system/multi-user.target.wants/firewalld.service to /usr/lib/systemd/system/firewalld.service.[root@router ~ 12:50:31]# firewall-cmd --set-default-zone=trustedsuccess[root@router ~ 12:50:53]# firewall-cmd --add-masquerade --permanent success
client2
网卡选vm1nmcli connection modify ens33 ipv4.address 10.1.1.21/24hostnamectl set-hostname client2.yuxb.cloud[root@client2 ~ 12:53:44]# ip rdefault via 10.1.8.2 dev ens33 proto static metric 100 10.1.1.0/24 dev ens33 proto kernel scope link src 10.1.1.21 metric 100 10.1.8.2 dev ens33 proto static scope link metric 100 [root@client2 ~ 12:53:52]# nmcli connection modify ens33 ipv4.gateway 10.1.1.20[root@client2 ~ 12:54:36]# nmcli connection up ens33 连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/2)[root@client2 ~ 12:54:41]# ip rdefault via 10.1.1.20 dev ens33 proto static metric 100 10.1.1.0/24 dev ens33 proto kernel scope link src 10.1.1.21 metric 100
http 模式
配置 web
web1.2.3都要配置# 给每台后端 Web 服务器额外准备一组“测试服务”# 部署 web[root@web1 ~ 15:06:47]# yum install -y nginx[root@web1 ~ 15:09:44]# echo Welcome to $(hostname) > /usr/share/nginx/html/index.html [root@web1 ~ 15:09:47]# systemctl enable nginx.service --nowCreated symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.[root@web1 ~ 15:09:47]# systemctl enable nginx.service --nowCreated symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.# 测试# 访问后端 nginx[root@client1 ~ 15:33:47]# curl 10.1.8.11Welcome to web1.yuxb.cloud[root@client1 ~ 15:34:06]# curl 10.1.8.12Welcome to web2.yuxb.cloud[root@client1 ~ 15:34:08]# curl 10.1.8.13Welcome to web3.yuxb.cloud# 准备虚拟主机[root@web1 ~ 15:09:48]# cat > /etc/nginx/conf.d/vhost-test.conf <<'EOF'> server {> listen 81;> root /test;> }> EOF[root@web1 ~ 15:11:40]# systemctl restart nginx# 准备测试文件[root@web1 ~ 15:11:51]# mkdir /test[root@web1 ~ 15:12:18]# echo hello txt from $(hostname -s) > /test/index.txt[root@web1 ~ 15:12:18]# echo hello html from $(hostname -s) > /test/index.html# 测试[root@client1 ~ 15:34:10]# curl http://web1:81/hello html from web1[root@client1 ~ 15:34:28]# curl http://web2:81/hello html from web2[root@client1 ~ 15:34:31]# curl http://web3:81/hello html from web3
配置 haproxy
情况1
# 轮询负载均衡[root@lb ~ 14:41:35]# yum install -y haproxy# 先备份一份再修改[root@lb ~ 15:14:05]# cp /etc/haproxy/haproxy.cfg{,.ori}[root@lb ~ 15:27:32]# vim /etc/haproxy/haproxy.cfg# 在最后添加frontend front_webbind *:80use_backend back_web#acl test url_reg -i \.txt$#use_backend test if testbackend back_webbalance roundrobinserver web1 10.1.8.11:80 checkserver web2 10.1.8.12:80 checkserver web3 10.1.8.13:80 check# frontend:定义前端,监听在 *:80# use_backend back_web:转发到 back_web# backend back_web:定义后端负载均衡池# balance roundrobin:轮询算法# check:启用健康检查,不可用的节点会被自动摘掉# 启动服务[root@lb ~ 15:31:35]# systemctl start haproxy# 测试# balance roundrobin → 轮询调度算法[root@client1 ~ 15:33:28]# curl http://lb.yuxb.cloud/Welcome to web1.yuxb.cloud[root@client1 ~ 15:33:36]# curl http://lb.yuxb.cloud/Welcome to web2.yuxb.cloud[root@client1 ~ 15:33:46]# curl http://lb.yuxb.cloud/Welcome to web3.yuxb.cloud# for循环测试[root@client2 ~ 15:40:06]# for i in {1..90}; do curl http://lb.yuxb.cloud; done[root@client2 ~ 15:40:25]# for i in {1..90}; do curl -s http://lb.yuxb.cloud; done | sort | uniq -c30 Welcome to web1.yuxb.cloud30 Welcome to web2.yuxb.cloud30 Welcome to web3.yuxb.cloud
情况二
# ACL 访问控制 + 轮询调度[root@lb ~ 15:32:48]# vim /etc/haproxy/haproxy.cfgfrontend front_webbind *:80default_backend back_webacl test url_reg -i \.txt$use_backend back_test if testbackend back_webbalance roundrobinserver web1 10.1.8.11:80 checkserver web2 10.1.8.12:80 checkserver web3 10.1.8.13:80 checkbackend back_testbalance roundrobinserver test1 10.1.8.11:81 checkserver test2 10.1.8.12:81 checkserver test3 10.1.8.13:81 check# bind *:80 → 前端监听 80 端口# default_backend back_web → 默认转发到 back_web (80 端口的 nginx)# acl test url_reg -i \.txt$ → 定义 ACL 规则:如果 URL 以 .txt 结尾# use_backend back_test if test → 如果匹配到 .txt 文件,就转发到 back_test[root@lb ~ 15:58:50]# systemctl restart haproxy# 测试[root@client2 ~ 15:40:58]# for i in {1..90}; do curl -s http://lb.yuxb.cloud/index.txt; done | sort | uniq -c 30 hello txt from web130 hello txt from web230 hello txt from web3# 普通请求 (/ 或 .html) → 走 80 端口后端# .txt 请求 → 走 81 端口后端,并且被 平均轮询到 web1/web2/web3
tcp 模式
配置 ssh
# 把 HAProxy 用来做 SSH 代理 + 轮询负载[root@lb ~ 15:59:26]# vim /etc/haproxy/haproxy.cfg########### ssh 代理 ###########listen sshmode tcpbind *:1022balance roundrobinserver web1 10.1.8.11:22 checkserver web2 10.1.8.12:22 checkserver web3 10.1.8.13:22 check# mode tcp → 因为 SSH 是 TCP 协议,所以要用 TCP 模式。# bind *:1022 → HAProxy 在自己的 1022 端口监听 SSH 连接。# balance roundrobin → 每个 SSH 连接会轮流转发到 web1/web2/web3 的 22 端口。[root@lb ~ 16:07:08]# systemctl restart haproxy# 测试# 只连lb:1022,HAProxy会轮流转发到后端的三台机器[root@client2 ~ 16:00:04]# ssh root@lb -p 1022 hostnameWarning: Permanently added '[lb]:1022,[10.1.8.10]:1022' (ECDSA) to the list of known hosts.web1.yuxb.cloud[root@client2 ~ 16:08:01]# ssh root@lb -p 1022 hostnameweb2.yuxb.cloud[root@client2 ~ 16:08:02]# ssh root@lb -p 1022 hostnameweb3.yuxb.cloud[root@client2 ~ 16:08:03]# ssh root@lb -p 1022Last login: Fri Aug 22 14:41:07 2025 from 10.1.8.1[root@web1 ~ 16:08:17]# 登出Connection to lb closed.
Nginx
简介
Nginx 是一个高性能的 Web 服务器,同时支持 反向代理 和 负载均衡。
常用于 Web 应用场景,支持静态资源服务、动静分离、反向代理、SSL 终端。
特点
轻量级,资源占用低,适合高并发场景。
反向代理:可以把请求转发给后端应用服务器。
负载均衡:内置多种调度算法。
模块化,扩展性强。
动静分离:静态文件由 Nginx 提供,动态请求交给后端。
常见负载均衡算法
round-robin
(轮询,默认)weight
(加权轮询,根据权重分配请求)ip_hash
(同一 IP 始终访问同一服务器,解决 session 问题)least_conn
(最少连接,分配给连接数最少的节点)
Nginx 实践
配置 router
最开始已经配过了
# 开启路由 echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf # 或者 # sed -i "s/ip_forward=0/ip_forward=1/g" /etc/sysctl.conf sysctl -p
配置 web
和haproxy一样
配置 Nginx 代理
# Nginx 反向代理 + 负载均衡# 在负载均衡器 lb 上安装 nginx [root@lb ~ 16:52:55]# yum install -y nginx# 配置 upstream 与代理规则 [root@lb ~ 16:52:55]# vim /etc/nginx/conf.d/proxy.conf [root@lb ~ 16:53:53]# cat /etc/nginx/conf.d/proxy.conf upstream web {server 10.1.8.11:80;server 10.1.8.12:80;server 10.1.8.13:80; } server {listen 80;server_name www.yuxb.cloud;root /usr/share/nginx/html;# Load configuration files for the default server block.include /etc/nginx/default.d/*.conf;location / {# 添加如下语句proxy_pass http://web;} }# upstream web {} 定义后端服务器池 (web1、web2、web3) # proxy_pass http://web; 把请求转发给 upstream 组 # 默认 round-robin 轮询算法,会依次把请求分发到 11、12、13[root@lb ~ 16:53:58]# systemctl restart nginx.service# 客户端域名解析 [root@client2 ~ 16:08:19]# echo "10.1.8.10 www.yuxb.cloud www" >> /etc/hosts [root@client1 ~ 15:35:47]# echo "10.1.8.10 www.yuxb.cloud www" >> /etc/hosts# 测试负载均衡效果 [root@client2 ~ 16:54:39]# curl http://www.yuxb.cloud Welcome to web1.yuxb.cloud [root@client2 ~ 16:55:10]# curl http://www.yuxb.cloud Welcome to web2.yuxb.cloud [root@client2 ~ 16:55:11]# curl http://www.yuxb.cloud Welcome to web3.yuxb.cloud
负载均衡-算法
[root@lb ~ 20:48:33]# vim /etc/nginx/conf.d/proxy.conf upstream web {server 10.1.8.11:80 weight=10;server 10.1.8.12:80 weight=20;server 10.1.8.13:80 weight=30; }[root@client2 ~ 20:50:37]# for i in {1..90}; do curl -s http://www.yuxb.cloud/; done | sort | uniq -c15 Welcome to web1.yuxb.cloud30 Welcome to web2.yuxb.cloud45 Welcome to web3.yuxb.cloud
Nginx 反向代理
实践:带路径匹配
[root@lb ~ 20:51:58]# cd /etc/nginx/conf.d/ [root@lb conf.d 20:52:03]# vim vhost-test.conf [root@lb conf.d 20:52:42]# cat vhost-test.conf server {listen 80;server_name www.yuxb.cloud;location /nginx1 {proxy_pass http://server1.yuxb.cloud/;}location /nginx2 {proxy_pass http://server2.yuxb.cloud/;} }[root@lb conf.d 20:54:49]# systemctl restart nginx# 访问测试 [root@client2 ~ 20:51:14]# curl http://www.yuxb.cloud/nginx1 Welcome to web1.yuxb.cloud [root@client2 ~ 20:55:20]# curl http://www.yuxb.cloud/nginx2 Welcome to web2.yuxb.cloud