四层负载均衡必须配置 mode tcp,禁用 mode http,否则 MySQL、Redis、SOCKS5 等二进制协议连接将失败;Ubuntu 用 apt 安装,需手动启用 systemd 日志并授权绑定特权端口。
直接上结论:四层负载均衡用 mode tcp,别写 mode http,否则后端根本收不到原始 TCP 流量,尤其代理类、MySQL、Redis 等场景会彻底失效。
确认系统环境与安装方式
Ubuntu/Debian 用 apt 最省事,CentOS/RHEL 用 yum 或 dnf;源码编译仅在需要特定版本或内核优化时才必要(比如要启用 nbthread)。
- Ubuntu 安装命令:
sudo apt update && sudo apt install haproxy - 安装后默认不启动,配置前先停掉:
sudo systemctl stop haproxy - 检查是否已启用 systemd 日志支持:
grep -q "haproxy" /lib/systemd/system/haproxy.service,若无则需手动补全ExecStartPre和日志路径
关键配置项必须设为 mode tcp
四层负载均衡的核心是透传原始 TCP 连接,不解析应用层内容。一旦在 defaults、frontend 或 backend 中误写 mode http,HAProxy 就会尝试解析 HTTP 头 —— 对 SOCKS5、SSR、MySQL 等纯二进制协议直接导致连接重置或超时。
-
defaults块里必须显式写:mode tcp(不能依赖注释或留空) -
frontend和backend若单独定义,也需各自声明mode tcp,避免被 defaults 覆盖但逻辑错位 - 不要在
frontend里配option httpchk—— 这是七层健康检查,四层只能用option tcp-check或默认的 TCP 握手探测
后端健康检查容易踩的坑
四层检查本质是 TCP connect() 是否成功,但默认行为可能不够敏感,尤其在代理链路中后端“假活”(端口通但服务卡死)时。
- 用
check启用检测,但别只靠默认:server web1 192.168.1.10:8080 check inter 3000 fall 3 rise 2 -
inter 3000是毫秒级,太短易误判,太长(如 30s)会导致故障发现延迟 - 若后端是 SOCKS5 或自定义协议,可加
tcp-check connect+tcp-check send发送探针,但需确保后端能响应,否则检查永远失败 - 注意
fall和rise数值要匹配实际网络抖动:内网建议fall 2 rise 2,跨公网建议fall 3 rise 3
监听地址和权限问题常被忽略
HAProxy 默认以 haproxy 用户运行,但非 root 用户无法绑定 1–1023 端口(如 bind *:80),而四层场景常需监听标准端口。
- 方案一:改用高权端口(如
bind *:8080),客户端配合调整 —— 最快验证方式 - 方案二:给 haproxy 二进制文件授权:
sudo setcap 'cap_net_bind_service=+ep' /usr/sbin/haproxy(systemd 环境下需额外加AmbientCapabilities=CAP_NET_BIND_SERVICE) - 方案三:用
chroot或user nobody时,确保/var/lib/haproxy目录属主为nobody,否则 stats socket 创建失败 - 若启用了
chroot,记得提前创建/var/lib/haproxy/dev/log并挂载devpts,否则日志不输出
四层配置真正难的不是语法,而是确认流量是否“原样透传”——建议用 tcpdump -i lo port 8080 在 backend 机器上抓包,看 payload 是否和客户端发出的一致;任何解码、重写、缓存行为都说明模式或选项设错了。
