一、负载均衡基础
1. 什么是负载均衡
简单来讲就是把用户的请求 "分摊" 给多台后端服务器,避免单台服务器扛不住压力,提升并发能力和服务可用性,还能隐藏后端服务器 IP,更加安全。
2. 负载均衡类型
- 硬件:F5、深信服 AD-1000 等(企业用得多)
- 四层 vs 七层 :
- 四层:基于 IP + 端口转发,像 LVS,速度快,不解析报文内容;
- 七层:基于应用层信息(URL、Cookie、请求头)转发,像 HAProxy、Nginx,功能更灵活,能做会话保持、动静分离。
二、HAProxy 核心认知
HAProxy 是法国大佬用 C 写的开源负载均衡器,主打高并发、高性能,支持 TCP(四层)和 HTTP(七层)代理,是企业里和 Nginx 并列的主流选择。我们实验用的是 2.4 版本,属于长期支持分支。
它的配置文件haproxy.cfg就分两大块:
- global:全局配置,管进程、连接数、日志这些 "全局参数";
- proxies:代理配置,包含 defaults(默认模板)、frontend(前端监听)、backend(后端服务器组)、listen(前后端合并,实验常用)。
三、HAProxy 核心配置
1. 基础配置框架
bash
#安装软件包:haproxy ~]# dnf install haproxy -y
#下载地址:https://github.com/haproxy/wiki/wiki/Packages
#查看版本:
[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
#多进程和socket文件配置如下:
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 100000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1 #启用多个sock文件
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
nbproc 2 #启用多进程
cpu-map 1 0 #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
cpu-map 2 1 #2 表示第二个进程,1表示第二个cpu核心
#查看多进程信息
haproxy haproxy]# pstree -p | grep haproxy
|-haproxy(4816)-+-haproxy(4820)
| `-haproxy(4821)
#启用多线程
haproxy ~]# vim /etc/haproxy/haproxy.cfg
...上面内容省略...
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 100000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1 #启用多个sock文件
stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
#nbproc 2
#cpu-map 1 0
#cpu-map 2 1
nbthread 2 #启用多线程
2. 调度算法
分静态 和动态,重点记这几个:
| 算法 | 类型 | 特点 | 适用场景 |
|---|---|---|---|
| static-rr | 静态 | 按权重轮询,不支持动态改权重 | 会话共享的 Web 集群 |
| roundrobin | 动态 | 按权重轮询,支持动态改权重、慢启动 | 默认首选,大部分 Web 场景 |
| leastconn | 动态 | 优先调度连接数少的服务器 | 长连接(如 MySQL) |
| source | 动静结合 | 基于客户端 IP 哈希,固定转发 | 无需 Cookie 的会话保持 |
3. 常用高级功能
(1)会话保持(基于 Cookie)
解决同一用户请求被分发到不同服务器导致的会话丢失问题:
bash
listen web_server
# 新增Cookie配置
cookie WEBCOOKIE insert nocache indirect
server rs1 192.168.0.101:80 cookie web1 check
server rs2 192.168.0.102:80 cookie web2 check
(2)状态页(监控必备)
能通过浏览器看 HAProxy 和后端服务器状态,排错方便:
bash
listen haproxy_stats
bind 0.0.0.0:8888
mode http
stats enable
stats uri /status # 访问路径
stats auth lee:lee # 账号密码
(3)IP 透传(日志记录真实 IP)
七层代理下,后端服务器默认只能看到 HAProxy 的 IP,需要配置透传:
bash
# HAProxy端加一行
option forwardfor except 127.0.0.0/8
# Nginx端修改日志格式,添加$http_x_forwarded_for
log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request"';
(4)ACL 访问控制(灵活转发 / 拦截)
ACL 就是 "条件判断",能根据域名、IP、URL、浏览器类型做不同处理,比如动静分离:
bash
frontend web_front
bind *:80
mode http
# 定义ACL:静态资源(图片、CSS)、动态资源(PHP)
acl static_file path_end -i .jpg .png .css .js
acl php_file path_end -i .php
# 匹配ACL转发到对应后端
use_backend static_rs if static_file
use_backend php_rs if php_file
default_backend default_rs
backend static_rs
server rs1 192.168.0.101:80 check
backend php_rs
server rs2 192.168.0.102:80 check
二、HAProxy 安装与核心参数配置
1、核心安装步骤
- 安装:在双网卡的 HAProxy 调度器上直接用
dnf安装,一键启用服务
bash
dnf install haproxy.x86_64 -y
systemctl enable --now haproxy # 开机自启+立即启动
2、最基础的负载均衡配置(两种写法)
1. 前后端分离(frontend+backend)
bash
frontend webcluster # 前端监听配置
bind *:80 # 监听所有网卡的80端口
mode http # 七层HTTP模式
use_backend webserver-80 # 调用后端服务器组
backend webserver-80 # 后端服务器组
# 定义后端服务器,开启健康检查(inter间隔3s,fall失败3次下线,rise成功5次上线)
server web1 192.168.0.10:80 check inter 3s fall 3 rise 5
server web2 192.168.0.20:80 check inter 3s fall 3 rise 5
2. 合并写法(listen,生产常用)
bash
frontend webcluster # 前端监听配置
bind *:80 # 监听所有网卡的80端口
mode http # 七层HTTP模式
use_backend webserver-80 # 调用后端服务器组
backend webserver-80 # 后端服务器组
# 定义后端服务器,开启健康检查(inter间隔3s,fall失败3次下线,rise成功5次上线)
server web1 192.168.0.10:80 check inter 3s fall 3 rise 5
server web2 192.168.0.20:80 check inter 3s fall 3 rise 5
三、HAProxy 实验环境搭建总结
一、实验环境拓扑核心
| 主机角色 | 网卡配置 | IP 地址 | 核心功能 |
|---|---|---|---|
| HAProxy 调度器 | eth0(外网)、eth1(内网) | 172.25.254.100/24、192.168.0.100/24 | 接收外网请求,转发到内网 Web 服务器 |
| WebServer1 | eth0(内网) | 192.168.0.10/24 | 提供 Web 服务,返回专属标识 |
| WebServer2 | eth0(内网) | 192.168.0.20/24 | 提供 Web 服务,返回专属标识 |
二、各主机核心配置步骤
1. HAProxy 调度器(关键:双网卡 + 路由转发)
(1)网卡配置
用vmset.sh脚本快速配置双网卡,注意内网网卡(eth1)加norouter避免自动生成默认路由:
bash
# 外网网卡(eth0):对外提供VIP访问
vmset.sh eth0 172.25.254.100 haproxy
# 内网网卡(eth1):连接后端Web服务器,norouter表示不设置默认路由
vmset.sh eth1 192.168.0.100 haproxy norouter
(2)开启内核路由转发(必配)
HAProxy 需要转发外网请求到内网,必须开启 IP 转发:
bash
echo net.ipv4.ip_forward=1 > /etc/sysctl.conf # 永久生效
sysctl -p # 立即生效,验证:输出net.ipv4.ip_forward = 1
2. 后端 Web 服务器(WebServer1/2,配置完全一致)
(1)网卡配置
仅配置内网 IP,加norouter避免和调度器路由冲突:
bash
# WebServer1
vmset.sh eth0 192.168.0.10 webserver1 noroute
# WebServer2
vmset.sh eth0 192.168.0.20 webserver2 noroute
(2)部署 Web 服务(Apache/httpd)
一键安装并配置专属页面,确保两台服务器返回内容可区分:
bash
# 安装httpd
dnf install httpd -y
# 写入专属标识页面(核心:区分不同服务器)
# WebServer1
echo webserver1 - 192.168.0.10 > /var/www/html/index.html
# WebServer2
echo webserver2 - 192.168.0.20 > /var/www/html/index.html
# 启动并开机自启httpd
systemctl enable --now httpd
三、环境验证(核心:网络连通性)
1. 基础连通性验证(HAProxy 主机执行)
确保 HAProxy 能访问两台后端 Web 服务器,这是负载均衡的前提:
bash
curl 192.168.0.10 # 应返回:webserver1 - 192.168.0.10
curl 192.168.0.20 # 应返回:webserver2 - 192.168.0.20
2. 验证要点说明
如果访问失败:
1.网卡IP是否配置正确(ip a)
2.防火墙是否关闭(systemctl stop firewalld)
3.Web服务器是否启动(systemctl status httpd)
HAProxy 加权轮询(static-rr)配置与热更新
bash
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
bind *:80
balance static-rr
server haha 192.168.0.10:80 check inter 3s fall 3 rise 5 weight 2
server hehe 192.168.0.20:80 check inter 3s fall 3 rise 5 weight 1
[root@haproxy ~]# systemctl restart haproxy.service
#测试
[Administrator.DESKTOP-VJ307M3] ➤ for i in {1..10}; do curl 172.25.254.100; done
webserver1 - 192.168.0.10
webserver1 - 192.168.0.10
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10
webserver1 - 192.168.0.10
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10
webserver1 - 192.168.0.10
webserver2 - 192.168.0.20
webserver1 - 192.168.0.10
#检测是否支持热更新
[root@haproxy ~]# echo "get weight webcluster/haha" | socat stdio /var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo "set weight webcluster/haha 1 " | socat stdio /var/lib/haproxy/stats Backend is using a static LB algorithm and only accepts weights '0%' and '100%'