Linux HAProxy 负载均衡配置方法

1次阅读

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

Linux HAProxy 负载均衡配置方法

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 必须定义在 frontendlisten 块内,backend 里不能定义新 ACL
  • 匹配路径用 path_begpath 更安全,避免 /api 错杀 /apisix
  • 多个 use_backend 按顺序匹配,第一个命中即终止,不继续往下判

配置里真正难的不是语法,是搞清每个参数背后对应的真实网络行为——比如 timeout server 不是“后端超时”,而是“HAProxy 等后端响应的最大时间”,它和后端自己的超时设置是两套逻辑,叠在一起容易互相掩盖问题。

text=ZqhQzanResources