Skip to content

HAProxy

HAProxy 常用于四层和七层负载均衡,配置重点在 frontendbackend、健康检查、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 -v

Debian / 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 httpchkHTTP 健康检查
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 backup

backup 表示备用后端,普通后端不可用时才接流量。数据库入口要特别谨慎,普通 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.localHost 等于指定域名,忽略大小写
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 check

Cookie 粘性:

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 web02

Cookie 方式适合 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 和日志配好就够用。