13.4.4 会话保持的超时与失效策略

会话保持的核心目标是在后端节点间维持同一客户端会话的粘性路由,但必须设计明确的超时与失效策略,避免“粘性表”膨胀与故障时错误会话延续。

文章图片

1. 超时策略设计与配置示例

# 文件: /etc/haproxy/haproxy.cfg
defaults
  mode http
  timeout connect 5s
  timeout client  60s
  timeout server  60s

backend bk_app
  balance roundrobin
  # 粘性表: 以源地址保持会话,30分钟过期,最大20万条
  stick-table type ip size 200k expire 30m store http_req_rate(10s)
  stick on src
  server app1 10.0.0.11:8080 check
  server app2 10.0.0.12:8080 check
  • timeout client/server:控制连接空闲超时,避免长时间无流量的连接占用资源。
  • stick-table expire 30m:设置粘性记录过期时间,与应用 Session/Token 时间对齐。

2. 失效策略与故障切换配置

# 文件: /etc/haproxy/haproxy.cfg
backend bk_app
  balance roundrobin
  stick-table type ip size 200k expire 30m
  stick on src
  # 当后端被标记为DOWN时清理粘性
  on-marked-down shutdown-sessions
  server app1 10.0.0.11:8080 check inter 2s fall 3 rise 2
  server app2 10.0.0.12:8080 check inter 2s fall 3 rise 2
  • on-marked-down shutdown-sessions:后端下线时立即清理关联会话,避免继续粘向故障节点。
  • fall/rise:故障判定与恢复阈值,降低误判。

3. 常见会话保持方式的失效控制示例

Cookie 粘性(推荐用于 Web)

backend bk_web
  balance roundrobin
  cookie SRV insert indirect nocache maxidle 30m maxlife 2h
  server web1 10.0.0.21:80 check cookie w1
  server web2 10.0.0.22:80 check cookie w2
  • maxidle 30m:空闲超时;maxlife 2h:最长存活。
  • 若后端变更,HAProxy 会更新 Cookie,避免旧节点粘性延续。

Header/URL 参数粘性(应用层会话标识)

backend bk_api
  balance roundrobin
  stick-table type string size 100k expire 20m
  stick on req.hdr(X-Session-ID)
  server api1 10.0.0.31:9000 check
  server api2 10.0.0.32:9000 check

4. 验证与排错命令

# 1) 检查配置语法
haproxy -c -f /etc/haproxy/haproxy.cfg

# 2) 重新加载并观察是否有会话重置
systemctl reload haproxy
journalctl -u haproxy -n 100 --no-pager

# 3) 通过 stats socket 查询粘性表使用情况
# 需要在配置中启用:
# global
#   stats socket /var/run/haproxy.sock mode 600 level admin
echo "show table bk_app" | socat /var/run/haproxy.sock stdio

# 4) 模拟客户端并观察粘性
curl -I http://lb.example.com/ -H "X-Session-ID: u1001"
curl -I http://lb.example.com/ -H "X-Session-ID: u1001"

常见排错指引
- 粘性失效过快:检查 stick-table expire 是否小于业务 Session 期限。
- 粘性不生效:检查 stick on 的键是否存在(Header/URL 未带标识)。
- 粘性表过大:确认 sizeexpire,观察是否存在“僵尸会话”。

5. 练习

1) 配置一套 stick-table 基于源地址的粘性,过期 10 分钟,验证 5 次请求均落到同一后端。
2) 将 app1 停止服务(或iptables阻断),观察 on-marked-down 后是否切换到 app2
3) 将粘性方式改为 X-Session-ID,删除该 Header 后验证请求是否随机分配。

6. 实践建议

  • 短会话业务使用较短粘性超时,长会话配合应用心跳与合理空闲超时。
  • 发布或故障时优先让粘性快速失效,以减少用户感知与负载倾斜。
  • 灰度发布建议使用短期粘性与可控的失效策略,避免用户长期固定在旧节点。