Appearance
HAProxy
HAProxy 常用于四层和七层负载均衡,配置重点在 frontend、backend、健康检查、ACL 路由、会话保持、统计页面和日志。
一、HAProxy 适合做什么
HAProxy 是一个专门做代理和负载均衡的服务。它既能代理 TCP,也能代理 HTTP。和 Nginx 相比,HAProxy 的后端健康检查、连接状态、统计页面和七层路由表达更直接。
常见链路:
几个核心概念:
| 概念 | 含义 |
|---|---|
global | 进程级配置,比如日志、进程数、最大连接 |
defaults | 默认参数,给 frontend/backend/listen 继承 |
frontend | 接收客户端请求的入口 |
backend | 后端服务器组 |
listen | 同时包含 frontend 和 backend 的简化写法 |
| ACL | 按请求内容做匹配和路由 |
我个人更喜欢用 HAProxy 管 API 和 TCP 入口,用 Nginx 管静态资源和普通 Web 反代。这不是绝对分工,只是 HAProxy 的状态和后端检查看起来更清楚。
二、安装
RHEL / Rocky / CentOS:
bash
yum install -y haproxy
systemctl enable --now haproxy
haproxy -vDebian / Ubuntu:
bash
apt update
apt install -y haproxy
systemctl enable --now haproxy
haproxy -v常见文件:
| 路径 | 用途 |
|---|---|
/etc/haproxy/haproxy.cfg | 主配置文件 |
/var/log/haproxy.log | 常见日志目标之一,取决于 rsyslog 配置 |
/usr/sbin/haproxy | 主程序 |
/run/haproxy/admin.sock | 管理 socket,可选 |
检查配置:
bash
haproxy -c -f /etc/haproxy/haproxy.cfg # 只检查配置,不启动三、基础 HTTP 负载均衡
示例配置:
haproxy
# /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
maxconn 10000
daemon
defaults
mode http
log global
option httplog
option dontlognull
option forwardfor
timeout connect 3s
timeout client 30s
timeout server 30s
frontend web_http
bind *:80
default_backend web_servers
backend web_servers
balance roundrobin
option httpchk GET /health
server web01 192.168.10.21:80 check
server web02 192.168.10.22:80 check关键点:
| 配置 | 说明 |
|---|---|
mode http | 按 HTTP 模式处理,能看 Header、URI、状态码 |
bind *:80 | 监听 80 端口 |
default_backend | 默认后端组 |
balance roundrobin | 轮询 |
option httpchk | HTTP 健康检查 |
option forwardfor | 给后端传递客户端真实 IP |
check | 对这个后端启用健康检查 |
加载:
bash
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl reload haproxy验证:
bash
curl -I http://127.0.0.1/四、TCP 负载均衡
TCP 模式适合 MySQL、Redis、普通 TCP 服务这类入口。
haproxy
frontend mysql_tcp
bind *:3306
mode tcp
default_backend mysql_servers
backend mysql_servers
mode tcp
balance source
server mysql01 192.168.10.31:3306 check
server mysql02 192.168.10.32:3306 check backupbackup 表示备用后端,普通后端不可用时才接流量。数据库入口要特别谨慎,普通 HAProxy TCP 转发不等于自动处理主从读写角色,后端角色切换要有额外控制。
五、ACL 路由
ACL 用来按请求特征选择后端。
haproxy
frontend web_http
bind *:80
acl host_api hdr(host) -i api.example.local
acl path_admin path_beg /admin/
acl path_static path_beg /static/
use_backend api_servers if host_api
use_backend admin_servers if path_admin
use_backend static_servers if path_static
default_backend web_servers常见匹配:
| ACL | 含义 |
|---|---|
hdr(host) -i api.example.local | Host 等于指定域名,忽略大小写 |
path_beg /api/ | 路径以 /api/ 开头 |
path_end .jpg .png | 路径以指定后缀结束 |
src 10.0.0.0/8 | 来源 IP 匹配网段 |
ACL 很方便,也容易越写越多。入口层规则开始大量包含业务语义时,发布前要多看一眼配置可读性和回滚方式。
六、会话保持
按源地址哈希:
haproxy
backend web_servers
balance source
server web01 192.168.10.21:80 check
server web02 192.168.10.22:80 checkCookie 粘性:
haproxy
backend web_servers
balance roundrobin
cookie SRV insert indirect nocache
server web01 192.168.10.21:80 check cookie web01
server web02 192.168.10.22:80 check cookie web02Cookie 方式适合 HTTP 应用,但后端扩缩容、故障摘除时仍然要考虑 session 是否能迁移。粘住后端只能减少漂移,不等于解决会话存储问题。
七、健康检查
HTTP 健康检查:
haproxy
backend web_servers
option httpchk GET /health
http-check expect status 200
server web01 192.168.10.21:80 check inter 2s fall 3 rise 2
server web02 192.168.10.22:80 check inter 2s fall 3 rise 2参数说明:
| 参数 | 含义 |
|---|---|
inter 2s | 每 2 秒检查一次 |
fall 3 | 连续失败 3 次认为不可用 |
rise 2 | 连续成功 2 次认为恢复 |
http-check expect status 200 | 期望 HTTP 200 |
健康检查路径要稳定、轻量。把数据库复杂查询放进去,会让 HAProxy 的检查也参与制造压力。
八、统计页面
开启 stats:
haproxy
listen stats
bind *:8404
mode http
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:strong_password_here访问:
text
http://192.168.10.10:8404/stats统计页能看到前后端状态、连接数、响应状态、健康检查结果。生产里这个端口只放给内网或运维网段,不放公网。
九、日志
HAProxy 常把日志交给 syslog。配置里:
haproxy
global
log 127.0.0.1 local2
defaults
log global
option httplog这里的 127.0.0.1 local2 表示 HAProxy 把日志发给本机 syslog,并使用 local2 这个 facility。rsyslog 要有对应接收和落盘规则,不然 HAProxy 配了日志也可能看不到文件。
rsyslog 示例:
conf
# /etc/rsyslog.d/haproxy.conf
local2.* /var/log/haproxy.log如果系统没有打开 UDP syslog 接收,可以补上本机 UDP 监听:
conf
# /etc/rsyslog.d/haproxy-udp.conf
module(load="imudp")
input(type="imudp" port="514")重启日志服务:
bash
systemctl restart rsyslog
systemctl reload haproxy
tail -f /var/log/haproxy.log日志里会有前端、后端、状态码和耗时。接口超时时,我会同时看 HAProxy 日志里的排队时间、连接时间、响应时间,再看后端应用日志。如果日志文件一直没有内容,先看 rsyslog 是否接到了 local2,再看 HAProxy 配置是否真的 reload 成功。
十、管理 socket
管理 socket 用来在命令行查看和调整 HAProxy 运行状态。普通环境只开 stats 页面也够用,但排查后端状态、临时下线节点时,socket 更直接。
在 global 里开启:
haproxy
global
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s查看信息:
bash
echo "show info" | socat - /run/haproxy/admin.sock
echo "show stat" | socat - /run/haproxy/admin.sock这个 socket 有管理权限,文件权限要收紧。线上临时摘后端可以通过 socket 做,但操作记录要能查到,不然事后很难确认当时谁把哪台节点切下去了。
十一、常见排查
常用命令:
bash
haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl status haproxy --no-pager
ss -lntp | grep haproxy
tail -f /var/log/haproxy.log常见问题:
| 现象 | 常见方向 |
|---|---|
| 配置加载失败 | 语法错误、缩进、关键字位置 |
| 503 | 后端全被摘除、backend 没可用 server |
| 504 | 后端响应超时 |
| 健康检查失败 | 路径不对、状态码不对、防火墙 |
| 只有一台后端有流量 | 会话保持、权重、长连接 |
| 真实 IP 丢失 | 没开 option forwardfor 或后端未信任代理 |
查看后端状态最直观的是 stats 页面。命令行里也可以通过 socket 做管理,但普通环境先把 stats 和日志配好就够用。