haproxy backend balance算法需按场景选择:http短连接用roundrobin;长连接(websocket/grpc)选leastconn;性能不均且需会话保持时用source+hash-type consistent。

haproxy.cfg 里 backend 的 balance 算法选哪个?
多数人直接写 balance roundrobin,但实际得看后端服务特性。HTTP 短连接用 roundrobin 没问题;如果后端是长连接(比如 WebSocket 或 gRPC),leastconn 更稳,避免单节点堆积太多连接;若后端节点性能差异大,得用 balance source 配合 hash-type consistent,否则 IP 哈希容易因节点增减导致大量会话重定向。
常见错误:把 source 当成“固定分发”,忘了默认 hash-type 是 map-based,节点变动时几乎全量漂移。必须显式写 hash-type consistent 才能缓解。
-
balance roundrobin:适合无状态、响应快的 HTTP 服务 -
balance leastconn:适合连接生命周期长、响应时间波动大的服务 -
balance source+hash-type consistent:适合需会话保持且集群动态扩缩的场景
健康检查 timeout 和 interval 怎么设才不误杀?
默认 check inter 2000 rise 2 fall 3 对很多 Java 应用来说太激进——Spring Boot 启动慢、GC 时响应卡顿几秒很常见,结果刚起来就被踢出集群。关键不是调大数值,而是让检查更贴合真实行为。
建议用 option httpchk GET /health 替代默认 TCP 探针,并在后端提供轻量级健康接口。同时把 inter 设为 5000ms 起步,fall 不低于 3,避免 GC 或日志刷盘瞬间触发误判。
- TCP 层检查(默认)只确认端口通,无法反映应用是否就绪
- HTTP 检查要确保后端
/health返回 2xx 且响应体不含 error 字样 -
timeout check必须显式设(如timeout check 3s),否则可能卡住整个检查队列
HTTPS 流量透传还是卸载?
90% 的误配置发生在 SSL 处理位置。如果后端是 Nginx/Tomcat 且已配好证书,别在 HAProxy 做 bind :443 ssl 再转发到后端 HTTPS —— 这属于重复加解密,徒增延迟和 CPU 开销。真需要加密链路,用 option ssl-hello-chk + TCP 透传更轻量。
只有当后端无法处理 TLS(比如老 PHP 应用)、或需统一 WAF/限流策略时,才做 SSL 卸载。此时务必关掉后端的 HTTP Strict Transport Security(HSTS)头自动注入,否则用户浏览器会拒绝降级到 HTTP,而 HAProxy 又没配好重定向逻辑,导致白屏。
- SSL 卸载:HAProxy 终止 TLS,用
http-request set-header X-Forwarded-Proto https通知后端 - TCP 透传:backend 用
mode tcp,不解析 HTTP,不设http-check - 混用风险:frontend HTTPS + backend HTTPS 未设
ssl-server-verify none会导致证书校验失败
ACL 规则为什么总不生效?
最常漏的是 use_backend 放错了位置。ACL 判断必须在 use_backend 之前定义,且不能跨 frontend/backend 区域引用。另一个隐形坑是大小写——hdr(host) -i example.com 中的 -i 表示忽略大小写,但若写成 -m str 就严格匹配,而域名通常带大写字母(比如某些 CDN 回源头),结果规则静默失效。
调试技巧:开 option http-log,看 access log 里 captured_req_hdr_0 实际值,比猜 header 名字靠谱得多。
- ACL 必须定义在
frontend或listen块内,backend里不能定义新 ACL - 匹配路径用
path_beg比path更安全,避免/api错杀/apisix - 多个
use_backend按顺序匹配,第一个命中即终止,不继续往下判
timeout server 不是“后端超时”,而是“HAProxy 等后端响应的最大时间”,它和后端自己的超时设置是两套逻辑,叠在一起容易互相掩盖问题。










