# Debian HAProxy 七层负载均衡配置:ACL、动静分离与健康检查
1. 服务介绍
HAProxy 是高性能 TCP/HTTP 代理和负载均衡软件。它可以在客户端与后端服务器之间接收请求,根据轮询、最少连接、域名、来源地址和 URL 路径等条件选择后端节点,并通过健康检查自动摘除故障服务器。
本文以 Debian Linux 为例,配置 HTTP 七层代理、后端轮询、域名与来源地址 ACL、动静分离和后端健康检查。适合内网 Web 集群、反向代理、灰度分流和多站点入口场景。
2. 准备运行环境
• 操作系统:Debian 10 示例环境;其他 Debian 版本配置结构基本一致。
• 操作账号:root 或具备 sudo 权限的管理员账号。
• 网络拓扑:HAProxy 主机能够访问所有后端 Web 服务器,客户端能够访问 HAProxy 监听地址。
• 软件要求:可通过 APT 安装 HAProxy;验证阶段建议准备 curl、ss 和 journalctl。
• 后端准备:至少两台提供相同内容的 Web 服务器,并明确服务端口、健康检查 URL 和返回状态码。
• 配置要求:修改前备份 /etc/haproxy/haproxy.cfg,先执行语法检查,再 reload 服务。
3. 相关知识
• frontend 定义监听地址和客户端请求入口,backend 定义后端节点、负载算法和健康检查。
• HTTP 七层代理可以读取 Host、路径和请求头;TCP 四层转发只能根据连接信息转发,不能直接按 HTTP URL 路径分流。
• roundrobin 适合后端处理能力接近的场景;leastconn 更适合请求耗时差异较大的场景。
• server ... check 开启后端健康检查。检查失败时,HAProxy 会暂时停止向该节点转发请求。
• ACL 规则从上到下匹配。use_backend 应放在默认后端之前,默认后端负责兜底,避免未匹配请求没有处理路径。
• TLS 透传使用 mode tcp,此时不能使用 HTTP 路径 ACL;需要按路径分流时,应在 HAProxy 终止 TLS 后使用 mode http。
• timeout connect、timeout client 和 timeout server 不能省略。超时过短会误判慢后端,过长会占满连接资源。
• 后端健康检查 URL 应返回稳定的 2xx/3xx 状态。不要只检查 TCP 端口而忽略应用实际是否可用。
4. 实验步骤
4.1 安装并检查 HAProxy
sudo apt update
sudo apt install -y haproxy
haproxy -v
确认版本输出正常后备份配置文件:
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak.$(date +%F-%H%M%S)
4.2 配置基础 HTTP 负载均衡
编辑 /etc/haproxy/haproxy.cfg,先配置一个最小可用的 HTTP 代理:
global
log /dev/log local0
log /dev/log local1 notice
stats socket /run/haproxy/admin.sock mode 660 level admin
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 30s
timeout server 30s
frontend web_front
bind *:80
default_backend web_backend
backend web_backend
balance roundrobin
option httpchk GET /health
server web1 172.18.206.180:8080 check
server web2 172.18.206.180:9090 check
/health 是示例检查路径,应替换为后端真实存在且能代表应用状态的 URL。如果后端没有该路径,可以先改为 /,但更推荐单独提供健康检查接口。
4.3 增加域名、端口和来源地址 ACL
HAProxy 可以根据 Host、目标端口和客户端来源地址选择不同后端。示例:
frontend multi_site
bind *:80
acl host_a hdr(host) -i a.example.com
acl host_b hdr(host) -i b.example.com
acl client_special src 192.168.1.140
acl port_8090 hdr(host) -m end :8090
use_backend special_backend if host_a client_special
use_backend port_backend if port_8090
use_backend site_b_backend if host_b
default_backend fallback_backend
backend special_backend
balance roundrobin
server special 192.168.1.174:80 check
backend port_backend
balance roundrobin
server port_web1 192.168.1.174:8090 check
server port_web2 192.168.1.178:8090 check
backend site_b_backend
server site_b 192.168.1.178:80 check
backend fallback_backend
server fallback 192.168.1.178:8080 check
同一条请求可能同时满足多个 ACL。示例中 special_backend 放在其他规则之前,保证特殊来源优先匹配;未命中规则的请求进入 fallback_backend。
4.4 配置动静分离
动静分离可以把 HTML、CSS、JavaScript、图片等静态请求交给静态服务器,把 PHP 或其他动态请求交给应用服务器:
frontend content_front
bind *:80
acl url_static path_end -i .html .css .js .jpg .jpeg .png .gif
acl url_dynamic path_end -i .php
use_backend static_backend if url_static
use_backend dynamic_backend if url_dynamic
default_backend dynamic_backend
backend static_backend
balance roundrobin
server static1 172.18.206.171:9090 check
backend dynamic_backend
balance roundrobin
server dynamic1 172.18.206.171:8080 check
路径匹配规则要结合实际 URL 设计。对于带查询参数的请求,通常使用 path、path_beg 或 path_reg 等 fetch 方法,并先用测试请求确认匹配结果。
4.5 HTTPS 场景选择代理模式
如果 HAProxy 只做 TLS 透传,使用 TCP 模式,无法读取加密后的 HTTP 路径:
frontend tls_passthrough
bind *:443
mode tcp
default_backend tls_backend
backend tls_backend
mode tcp
balance roundrobin
server tls1 172.18.206.184:443 check
server tls2 172.18.206.185:443 check
如果需要按域名、路径或请求头分流,应在 HAProxy 终止 TLS,配置证书后改用 HTTP 模式。证书文件应由管理员按实际权限准备,不能把私钥写入公开文档或提交到代码仓库。
4.6 检查配置并启动服务
修改完成后先检查语法:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
语法检查通过后启用并启动服务:
sudo systemctl enable --now haproxy
sudo systemctl reload haproxy
如果 reload 失败,先查看 systemd 状态和 HAProxy 日志,不要直接覆盖备份配置。
5. 验证结果
5.1 检查服务和监听端口
systemctl status haproxy --no-pager
ss -lntp | grep -E ':(80|443)( |$)'
journalctl -u haproxy -n 50 --no-pager
确认 HAProxy 处于 active 状态,并监听预期端口。
5.2 验证 Host 和后端分流
从 HAProxy 主机或客户端发起带 Host 的请求:
curl -I -H "Host: a.example.com" http://127.0.0.1/
curl -sS -o /dev/null -w "%{http_code} %{remote_ip}\n" -H "Host: a.example.com" http://127.0.0.1/
curl -I -H "Host: b.example.com" http://127.0.0.1/
多次请求后检查后端访问日志,确认轮询后端收到请求;如果业务响应中包含节点标识,也可以用节点标识直接判断分流结果。
5.3 查看后端健康状态
安装 socat 后,可以通过 HAProxy 管理 socket 查看后端状态:
sudo apt install -y socat
echo "show stat" | sudo socat stdio /run/haproxy/admin.sock
检查输出中的后端和服务器状态。UP 表示健康检查通过,DOWN 表示节点当前不会接收新请求。验证时可以临时停止一台后端服务,确认请求仍能由其他健康节点处理。
6. 常见问题
• **配置检查失败**:执行 haproxy -c -f /etc/haproxy/haproxy.cfg 定位行号,检查缩进、关键字和端口格式。
• **服务启动但端口未监听**:检查 bind 地址是否被其他进程占用,并查看 journalctl -u haproxy。
• **后端全部 DOWN**:从 HAProxy 主机测试后端地址和端口,确认防火墙、路由、健康检查 URL 和返回状态码。
• **ACL 没有命中**:打印实际 Host 头,注意 Host 可能包含端口;逐条验证规则,确认特殊规则位于默认后端之前。
• **HTTPS 按路径分流失败**:检查是否仍在 mode tcp 下使用路径 ACL。TLS 透传不能读取加密 HTTP 内容,需要终止 TLS 后改用 mode http。
• **reload 后连接异常**:检查 timeout 设置、后端响应时间和连接数,再查看 HAProxy 日志与后端日志。
• **修改后需要回退**:恢复最近一次可用配置,重新执行语法检查,再 reload;不要在语法未通过时重启生产服务。

7579

被折叠的 条评论
为什么被折叠?



