【Day 61】Linux-haproxy负载均衡
一、HAProxy 介绍
HAProxy 是一款开源的高性能负载均衡器,支持4 层(传输层) 和7 层(应用层) 负载均衡,广泛应用于高并发服务架构中。
二、HAProxy 核心配置文件解析
主配置文件为/etc/haproxy/haproxy.cfg
核心结构包括 frontend(前端虚拟服务)和 backend(后端服务器池)。
一、global 部分:全局配置,影响 HAProxy 整体运行的参数
global
log 127.0.0.1 local2 # 日志配置:输出到本地 127.0.0.1 的 local2 设备(需配合 rsyslog 配置)
chroot /var/lib/haproxy # 改变 HAProxy 的根目录为 /var/lib/haproxy,增强安全性(限制文件系统访问)
pidfile /var/run/haproxy.pid # 指定 PID 文件路径,用于进程管理
maxconn 4000 # 全局最大并发连接数限制
user haproxy # 运行 HAProxy 的用户
group haproxy # 运行 HAProxy 的用户组
daemon # 以守护进程(后台)模式运行
# 启用统计信息的 Unix 套接字,用于通过 socket 获取 HAProxy 状态(如 echo "show stats" | socat /var/lib/haproxy/stats stdio)
stats socket /var/lib/haproxy/stats二、defaults 部分:默认配置,适用于所有 frontend 和 backend(可被局部配置覆盖)
defaults
mode http # 默认工作模式为 HTTP(7 层负载均衡)
log global # 继承 global 部分的日志配置
option httplog # 启用 HTTP 日志记录(记录更详细的 HTTP 请求信息)
option dontlognull # 不记录空连接(无数据传输的连接)
option http-server-close # 每次请求后关闭与后端服务器的连接,优化连接复用
option forwardfor except 127.0.0.0/8 # 向后端传递客户端真实 IP(通过 X-Forwarded-For 头),排除本地 IP 段
option redispatch # 当后端服务器故障时,将请求重新分配到其他健康服务器
retries 3 # 连接后端服务器失败时的重试次数
timeout http-request 10s # 等待 HTTP 请求的超时时间(从接收连接到完整接收请求)
timeout queue 1m # 请求在队列中等待被处理的超时时间
timeout connect 10s # 与后端服务器建立连接的超时时间
timeout client 1m # 客户端连接的超时时间(从建立连接到关闭)
timeout server 1m # 与后端服务器连接的超时时间(从建立连接到关闭)
timeout http-keep-alive 10s # HTTP 长连接的超时时间
timeout check 10s # 健康检查的超时时间
maxconn 3000 # 每个 frontend/backend 的默认最大并发连接数三、frontend 部分:定义前端虚拟服务,接收客户端请求并转发到后端frontend 前端服务名称 bind IP: 端口 #或简写为 frontend 服务名 IP: 端口mode {tcp|http} #定义 frontend 处理请求的协议层级,需与后端(backend)的 mode 保持一致acl 规则名 匹配方法 -i 匹配条件空格分隔 # 访问控制列表,实现 “按请求特征匹配”use_backend 后端服务名 if 已定义的 ACL 规则名 # 客户端请求命中 “if” 后的 ACL 规则时,将请求转发到指定的后端服务器池default_backend 后端服务名 # 客户端请求未命中任何 “use_backend” 的 ACL 规则时,默认转发到指定的后端服务器池四、backend 部分:定义后端服务器集群,处理前端转发的请求backend 后端 # 例:backend static 静态资源后端(处理图片、CSS、JS 等)balance {roundrobin|source|least} # 调度算法:轮询(按顺序分配请求到后端服务器)mode {tcp|http} # 协议模式(必须与frontend一致)server 名称1 IP:端口 [参数] # 参数:check(健康检查)、weight(权重)、backup(备用节点)server 名称2 IP:端口 #例子:server static 127.0.0.1:4331 check # 后端服务器:名称为 static,地址 127.0.0.1:4331,启用健康检查(check)
调度核心:ACL(访问控制列表)
ACL 用于匹配 HTTP 请求特征(如主机名、URL 等),实现基于规则的转发。常用 ACL 规则:
规则语法 | 作用 | 示例 |
---|---|---|
| 正则匹配主机名(-i 忽略大小写) |
|
| 精确匹配主机名 |
|
| 匹配 URL 以指定后缀结尾 |
|
| 匹配 HTTP 请求方法(GET/POST 等) |
|
三、HAProxy 实现 MySQL 4 层负载均衡
前置条件
- 后端 2 台 MySQL 服务器已配置双主复制,确保数据同步。这里用了两主一从。
- MySQL需要有一个用户用来连接,检验。
- 需设置auto_increment_offset和auto_increment_increment避免主键冲突(如 db01 设offset=1, increment=2,db02 设offset=2, increment=2)。
- 防火墙开放 3306 端口(或临时关闭防火墙:systemctl stop firewalld)。
1. 安装 HAProxy
# 安装软件(CentOS系统)
yum install -y haproxy# 备份默认配置文件(重要)
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
2. 配置 MySQL 负载均衡
vim /etc/haproxy/haproxy.cfg
frontend dbbind 0.0.0.0:3306mode tcp use_backend db_server backend db_serverbalance roundrobinmode tcpserver db01 192.168.140.51:3306 checkserver db02 192.168.140.158:3306 checkserver db03 192.168.140.159:3306 check
3. 启动并验证 HAProxy
# 启动服务并设置开机自启
systemctl enable --now haproxy# 检查服务状态(确保active (running))
systemctl status haproxy# 验证端口监听(3306端口已被haproxy占用)
ss -tunlp | grep haproxy
# 预期输出:tcp LISTEN 0 100 0.0.0.0:3306 0.0.0.0:* users:(("haproxy",pid=xxx,fd=xxx))
4. 测试 MySQL 负载均衡
在客户端机器上通过 HAProxy 连接 MySQL:
# 连接HAProxy(替换为HAProxy服务器IP)
mysql -h 192.168.1.20 -P 3306 -u root -p# 验证连接(在MySQL终端执行,查看当前连接的后端节点)
# 方法1:在db01/db02上执行`show processlist;`,观察客户端连接的IP是否为HAProxy
# 方法2:在db01创建测试表,db02验证是否同步(测试主从复制)
四、HAProxy 实现 Web 7 层负载均衡
前置条件
- 后端 2 台 Web 服务器(示例:web01:192.168.140.20、web02:192.168.140.30)已部署 Nginx/httpd
- 分别提供blog.linux.com和cart.linux.com服务。
- 所有域名解析至 HAProxy 服务器 IP(192.168.140.10)。
(1)20
[root@host-20 ~] cd /etc/httpd/conf.d/
[root@host-20 conf.d] vim blog.conf
[root@host-20 conf.d] vim cart.conf
[root@host-20 conf.d] mkdir /{blog,cart}
[root@host-20 conf.d] ip addr add dev ens33 192.168.140.222/24
[root@host-20 conf.d] echo "ip addr add dev ens33 192.168.140.222/24" > /etc/rc.d/rc.local
[root@host-20 conf.d] chmod a+x /etc/rc.d/rc.local
[root@host-20 conf.d] echo "20 blog" >/blog/index.html
[root@host-20 conf.d] echo "20 cart" >/cart/index.html
[root@host-20 conf.d] systemctl enable --now httpd
(2)30的
1. 安装 HAProxy
2.配置 Web 7 层负载均衡
vim /etc/haproxy/haproxy.cfg
frontend webbind 0.0.0.0:80mode http # 7层HTTP模式option forwardfor # 向后端添加X-Forwarded-For头(传递客户端真实IP)option http-server-close # 关闭与后端的连接,优化性能# 定义ACL规则acl blog_acl hdr_reg(host) -i ^blog\..*$ # 匹配blog.开头的域名,正则acl cart_acl hdr_dom(host) -i cart.linux.com # 精确匹配cart.linux.com# 规则转发use_backend blog if blog_acluse_backend cart if cart_acldefault_backend cart # 默认后端(无匹配规则时)backend blogmode httpbalance roundrobin # 轮询调度server web01 192.168.140.30:80 check # 健康检查server web02 192.168.140.20:80 check backend cartmode httpbalance leastconn # 最少连接调度server web01 192.168.140.30:80 check server web02 192.168.140.20:80 check
3. 重启 HAProxy 并验证
# 重启服务
systemctl restart haproxy# 验证80端口监听
ss -tunlp | grep haproxy
# 预期输出:tcp LISTEN 0 100 0.0.0.0:80 0.0.0.0:* users:(("haproxy",pid=xxx,fd=xxx))
4. 测试 Web 负载均衡
- 访问测试:在客户端浏览器访问
http://blog.linux.com
和http://cart.linux.com
,应分别返回对应后端服务内容。
5. 配置日志记录真实客户端 IP
默认日志记录的是 HAProxy 的 IP,需修改日志格式以获取客户端真实 IP(
(1)Nginx
vim /etc/nginx/nginx.conf # 或对应虚拟主机配置文件
log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent"';
nginx -t
(2)httpd
vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
httpd -t
systemctl restart httpd
注意:配置文件中的option forwardfor except 127.0.0.0/8
验证日志:
tail -f /var/log/nginx/access.log
# 预期输出中$http_x_forwarded_for字段为客户端真实IP
[root@web01 ~]# tail -n 3 /usr/local/nginx/logs/opencart_access.log
192.168.140.1 - - [08/Jun/2024:15:30:35 +0800] "GET /image/cache/catalog/demo/product/product-5-300x300.png HTTP/1.1" 404 153 "http://opencart.linux.com/index.php?route=product/category&path=20_26" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0"
192.168.140.1 - - [08/Jun/2024:15:30:35 +0800] "GET /image/cache/catalog/demo/slideshow/banner-2-287x403.png HTTP/1.1" 404 153 "http://opencart.linux.com/index.php?route=product/category&path=20_26" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0"