HAProxy:常见问题
发布时间:2026-04-23 16:01
一、前言
搞过的人都清楚,HAProxy出故障时那叫一个蛋疼——连接莫名其妙被重置、后端明明活着却报502、日志刷得飞起却找不到线索。这玩意儿配置看着简单,真出问题了排查起来能把人逼疯。今天把生产环境踩过的坑整理一遍,帮你省掉半夜爬起来的时间。
二、操作步骤
第1步:确认HAProxy进程状态
# CentOS/RHEL
systemctl status haproxy
# Ubuntu
sudo systemctl status haproxy
预期输出:
● haproxy.service - HAProxy Load Balancer
Loaded: loaded (/lib/systemd/system/haproxy.service; enabled)
Active: active (running) since Thu 2024-01-11 10:30:00 CST; 2h ago
Docs: man:haproxy(1)
Main PID: 1234 (haproxy)
Tasks: 6 (limit: 4096)
Memory: 15.2M
CSD: not required
如果看到active (running)说明进程活着,没反应的话先检查配置文件语法。
第2步:验证配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
预期输出:
Configuration file is valid
如果报语法错误,这里会指出具体行号和原因。生产环境改配置前必做这步,别问我怎么知道的。
第3步:查看实时日志定位错误
# 查看HAProxy日志(CentOS/RHEL)
tail -f /var/log/haproxy.log
# Ubuntu默认syslog
tail -f /var/log/syslog | grep haproxy
预期输出(典型错误示例):
Jan 11 10:35:22 web01 haproxy[1234]: backend www_pool has no server available!
Jan 11 10:36:05 web01 haproxy[1234]: Server www_pool/web01 is DOWN, reason: Layer4 timeout
Jan 11 10:37:10 web01 haproxy[1234]: 10.0.0.50:33345 [11/Jan/2024:10:37:10.123] frontend~ www_pool/web01 0/0/0/-1/5003 503 2129 - - cR-- 1/1/0/0/0 0/0 "GET /api/health HTTP/1.1"
503 + cR标志说明后端全部宕机或者健康检查全挂。cR表示client连接被重置后立即关闭。
第4步:排查健康检查失败
# 测试后端真实存活状态(从HAProxy主机上执行)
curl -v http://10.0.0.101:8080/health
预期输出:
< HTTP/1.1 200 OK
< Content-Type: text/plain
ok
# 检查后端端口监听
netstat -tlnp | grep 8080
预期输出:
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1234/nginx
如果后端curl正常但HAProxy还是标记DOWN,说明健康检查配置有问题或者网络不通。
第5步:检查后端服务器连通性
# 从HAProxy主机ping后端(注意:HAProxy做TCP层检查不会ping)
# 直接telnet测试端口连通
telnet 10.0.0.101 8080
Trying 10.0.0.101...
Connected to 10.0.0.101.
Escape character is '^]'.
# 也可以用nc
nc -zv 10.0.0.101 8080
预期输出:
Connection to 10.0.0.101 8080 port [tcp/*] succeeded!
防火墙是最常见的坑,HAProxy和后端之间如果有iptables拦住,健康检查永远失败。
第6步:排查504网关超时
# 检查haproxy.cfg里的timeout设置
cat /etc/haproxy/haproxy.cfg | grep -E "timeout|timeout"
预期输出:
timeout connect 5000ms
timeout server 30000ms
timeout client 30000ms
# 查看当前连接数和状态
socat /var/run/haproxy/admin.sock stdio <<< "show stat" | grep -E "backend|frontend" | head -20
预期输出:
# pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout...
www_pool,FRONTEND,,,3,10,2000,1500,125000,8900000,,1,,,,,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
www_pool,web01,0,5,3,10,,200,124000,8900000,0,0,,1,0,0,0,0,,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
504通常是timeout server设置太短或者后端处理太慢。重点看后端的stot(总请求数)和bin/bout(流量),如果长时间没变化说明后端卡住了。
第7步:确认绑定地址冲突
# 检查端口占用
netstat -tlnp | grep :80
预期输出:
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1234/haproxy
# 如果有其他进程占着,HAProxy启动会直接报错
haproxy -c -f /etc/haproxy/haproxy.cfg
预期输出:
[ALERT] 1234/103522 (12345) : parsing [/etc/haproxy/haproxy.cfg:15] : bind '0.0.0.0:80' : cannot bind to address (98) Address already in use
三、常见问题FAQ
Q:后端服务正常但HAProxy一直报no server available,什么鬼?
先别急着骂HAProxy,大概率是这几个原因:健康检查interval设太长了(有时候要等30秒才标记UP);后端权重是0你没注意;最大连接数scur满了,新连接直接被拒;网络层面防火墙拦截了HAProxy到后端的探测包。用第4步的curl手动测一遍,比看日志快。
Q:HAProxy突然大量报503,后端其实都活着,怎么排查?
这种最坑,往往是后端应用hang住了但进程还在。快速定位步骤:1)用show stat看后端qcur有没有积压;2)登上去top看看CPU和内存;3)查数据库连接池有没有耗尽;4)检查后端日志有没有GC停顿或者超时。有时候不是HAProxy的问题,是后端在请求外部依赖超时拖累的。
Q:HAProxy拿到的client IP全是内网IP,后端日志里全是HAProxy的IP,怎么解决?
如果是HTTP服务,HAProxy默认会X-Forwarded-For头,但有些老应用不看这个。解决方案是在HAProxy配置里加option forwardfor,然后在后端Nginx里配置real_ip_recursive和set_real_ip_from。如果是非HTTP的TCP代理,那没辙,要么前端链路加密,要么换走七层。
Q:HAProxy配置改了但reload后新请求还是走的旧后端,缓存问题吗?
HAProxy不是nginx,reload不会缓存任何东西。检查后端状态:先用show stat确认新后端是否已经UP,如果UP了那就是你的客户端在做连接池复用。换个curl命令加-C参数强制关闭keepalive试试。另外注意server指令里的source参数,如果用了source 0.0.0.0那么可能存在路由层面的问题。
Q:生产环境想改HAProxy配置又不想断连,怎么做?
用systemctl reload haproxy不是restart,HAProxy会等待现有连接自然结束后再切换,不会丢请求。但注意:如果配置里改了bind地址或者动了global里的maxconn,需要full restart。安全的改法是先改配置、语法检查、reload,然后观察show stat确认无异常。别直接sed -i改完就reload,生产环境出过事的。
四、总结
核心要点:
- 出现问题先看进程状态+配置文件语法,这两步能排除一半低级错误
- 日志是排查的主力,/var/log/haproxy.log和syslog都要看,注意日志级别配置
- 健康检查是高频故障点,务必从HAProxy主机手动验证后端可达性
- 504/503先看timeout配置,再看后端真实状态,最后查数据库和外部依赖
- reload不断连,restart才断连,非必要不restart
延伸阅读:
- HAProxy官方配置文档:https://www.haproxy.org/documentation/
- HAProxy stats socket命令官方参考
- 《Linux高性能服务器编程》相关章节
- iptables规则检查(生产环境改动必须两人确认)
⚠️ 警告:iptables -F和类似清空操作会导致服务器网络中断,必须在本地console操作,禁止远程执行。