13.4.5 算法与会话保持的实践选择与注意事项

实践选择与注意事项#

在生产环境中选择负载均衡算法与会话保持方式,应结合业务状态模型、节点能力、跨机房成本与故障恢复目标,避免“一刀切”。本节给出可操作的选择策略、配置示例、排错与练习。

原理草图(会话保持与算法选择关系)

文章图片

实践选择建议(带示例)
- 无状态服务优先:会话下沉至 Redis/数据库,使用 roundrobinleastconn

# /etc/haproxy/haproxy.cfg
frontend fe_http
  bind *:80
  default_backend be_app

backend be_app
  balance roundrobin
  option httpchk GET /health
  server app1 10.0.0.11:8080 check
  server app2 10.0.0.12:8080 check

预期效果:新增/下线节点时会话不丢,流量均匀分布。

  • 有状态服务保留粘性:使用 cookie 粘性或 stick-table
backend be_stateful
  balance roundrobin
  cookie SRV insert indirect nocache
  server s1 10.0.1.11:8080 cookie s1 check
  server s2 10.0.1.12:8080 cookie s2 check

预期效果:同一客户端携带 SRV Cookie 时会被固定到同一后端。

  • 节点能力不均衡:加权调度。
backend be_weight
  balance leastconn
  server high 10.0.2.11:8080 weight 5 check
  server low  10.0.2.12:8080 weight 1 check

预期效果:高配节点承担更多连接。

  • 长连接业务(WebSocket/MQTT):使用 source + 合理超时。
backend be_ws
  balance source
  timeout tunnel 1h
  server ws1 10.0.3.11:9001 check
  server ws2 10.0.3.12:9001 check

预期效果:同源地址稳定落点,连接不易频繁重连。

  • 缓存场景:URI/Header 哈希提升命中率。
backend be_cache
  balance uri
  hash-type consistent
  server c1 10.0.4.11:8081 check
  server c2 10.0.4.12:8081 check

预期效果:缓存命中率提升,但扩缩容需评估重分布影响。

关键注意事项(可执行检查)
- 粘性与高可用冲突:节点故障时会话保持会影响无感切换,需健康检查+快速重试。

defaults
  option redispatch 1
  retries 2
  timeout connect 5s

说明:后端不可用时自动重分配,降低粘性带来的切换失败。

  • stick-table 容量与过期:避免 OOM。
backend be_stick
  stick-table type ip size 200k expire 30m store http_req_rate(10s)
  stick on src

说明:合理设置 sizeexpire,避免表膨胀。

  • Cookie 安全:避免泄露后端信息。
backend be_cookie_safe
  cookie SRV insert indirect nocache
  http-response set-header Set-Cookie "SRV=%[cookie(SRV)]; HttpOnly; Secure"

说明:HttpOnly/Secure 减少被窃取风险。

  • 算法切换影响:变更算法会导致会话分布变化,应在低峰期并评估缓存失效。

安装与验证(本节实践环境)

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y haproxy

# CentOS/RHEL
sudo yum install -y haproxy

# 查看版本与配置语法
haproxy -v
haproxy -c -f /etc/haproxy/haproxy.cfg

完整示例:带粘性与权重的组合

# /etc/haproxy/haproxy.cfg
global
  log /dev/log local0
  maxconn 4000

defaults
  mode http
  log global
  option httplog
  timeout connect 5s
  timeout client  30s
  timeout server  30s
  option redispatch 1

frontend fe_http
  bind *:80
  default_backend be_mix

backend be_mix
  balance leastconn
  cookie SRV insert indirect nocache
  server app1 10.0.10.11:8080 weight 3 cookie a1 check
  server app2 10.0.10.12:8080 weight 1 cookie a2 check

命令解释与操作步骤

# 1) 校验配置
haproxy -c -f /etc/haproxy/haproxy.cfg
# 输出 "Configuration file is valid" 表示通过

# 2) 启动/重载
sudo systemctl enable --now haproxy
sudo systemctl reload haproxy

# 3) 验证会话保持(查看响应头中的 Set-Cookie)
curl -I http://<LB_IP>/
# 预期看到: Set-Cookie: SRV=a1 或 SRV=a2

排错清单(含命令)
- 粘性失效:确认响应头是否注入 Cookie;检查前端是否有反向代理剥离头。

curl -I http://<LB_IP>/ | grep -i set-cookie
  • 流量不均:检查权重与算法是否被覆盖。
grep -n "balance" /etc/haproxy/haproxy.cfg
  • 会话丢失:查看后端健康状态与重分配。
journalctl -u haproxy -n 200 | grep -i "redispatch\|server"

练习
1. 将 balance roundrobin 改为 leastconn,观察并发连接下的分配差异。
2. 为 be_mix 增加 stick-table(基于源 IP),比较 Cookie 粘性与 IP 粘性差异。
3. 模拟下线 app2(停止服务),验证 option redispatch 是否生效。
4. 调整权重为 app1:1, app2:3,统计 100 次请求分布情况。