HAProxy 如何配置 Stick Table 实现会话保持 sticky session

文章导读
HAProxy 通过在后端配置 stick-table 存储客户端标识,配合 stick-on 指令将同一标识的请求固定转发到特定服务器,实现会话保持。适用于需要维持登录状态或购物车数据的 Web 应用,风险在于表满后新会话可能无法保持。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

HAProxy 通过在后端配置 stick-table 存储客户端标识,配合 stick-on 指令将同一标识的请求固定转发到特定服务器,实现会话保持。适用于需要维持登录状态或购物车数据的 Web 应用,风险在于表满后新会话可能无法保持。

先说结论:Stick Table 是 HAProxy 实现应用层会话保持的标准方案,比 balance source 更灵活。

  • 适合:基于 Cookie、IP 或 URL 参数的会话跟踪场景。
  • 先准备:评估并发连接数以确定 table size 和内存占用。
  • 验收:通过 Stats Socket 查看表项命中情况。

命令速用版

以下配置片段可直接放入 HAProxy 配置文件的 backend 段落,实现基于源 IP 的会话保持。

backend web_servers
    balance roundrobin
    stick-table type ip size 100k expire 30m
    stick on src
    server web1 192.168.1.10:80 check
    server web2 192.168.1.11:80 check

若需基于 Cookie 保持,将 stick on src 改为 stick on hdr(cookie) 并配合 cookie 插入指令。

为什么会这样

HTTP 协议本身是无状态的,HAProxy 需要在内存中建立映射关系才能记住客户端上次访问的服务器。Stick Table 本质上是一块共享内存区域,用于存储客户端标识(如 IP 地址)与后端服务器 ID 的对应关系。当新请求到达时,HAProxy 查询该表,若找到匹配项则强制转发到记录中的服务器,否则按负载均衡算法选择新服务器并更新表项。

分步处理

第一步:定义 Stick Table

在 backend 段落中使用 stick-table 指令定义表类型和大小。类型通常为 ip 或 string,大小需根据预期并发会话数设定。

stick-table type ip size 500k expire 1h

第二步:配置存储规则

HAProxy 如何配置 Stick Table 实现会话保持 sticky session

使用 stick store-request 指令告诉 HAProxy 哪些请求需要被记录到表中。通常配合条件使用,避免记录健康检查请求。

stick store-request src

第三步:设置匹配条件

使用 stick on 指令指定匹配键值。当请求的键值与表中现有记录匹配时,触发会话保持。

stick on src

第四步:选择负载均衡算法

会话保持生效前,首次请求仍需负载均衡。建议搭配 roundrobin 或 leastconn,避免与 source 算法冲突。

balance roundrobin

怎么验证是否生效

通过 HAProxy 的 Stats Socket 或 HTTP Stats 页面查看 Stick Table 内容。使用 socat 命令连接 socket 并查询表状态。

HAProxy 如何配置 Stick Table 实现会话保持 sticky session
echo "show table web_servers" | socat stdio /var/run/haproxy.sock

输出中应看到 client_ip 对应的 server_id 字段。连续发起请求,观察同一 IP 是否始终指向同一 server_id。若使用 HTTP Stats 页面,可在 Backend 部分找到 Stick Table 条目查看计数。

常见坑

表空间已满:当 stick-table 达到 size 上限,新会话无法记录,导致会话保持失效。监控 haproxy_frontend_stick_table_size 指标,预留 20% 余量。

过期时间过短:expire 设置过短会导致用户正常操作期间会话失效。建议根据业务会话时长设置,通常 30 分钟至 2 小时。

NAT 环境 IP 相同:基于 src IP 保持在大公司或 NAT 出口环境下会导致所有用户指向同一服务器。此时应改用 Cookie 或特定 Header 作为键值。

常见问题

Stick Table 和 balance source 有什么区别?

balance source 仅基于 IP 哈希且不可配置过期时间,Stick Table 支持 Cookie、Header 等多种键值且可管理生命周期。

Stick Table 满了会发生什么?

新请求无法写入表项,会话保持失效,请求按普通负载均衡算法分发,不会导致服务中断。

如何清空 Stick Table?

通过 Stats Socket 发送 clear table <backend_name> 命令可清空指定后端表项,生产环境慎用。

参考来源

  • HAProxy Configuration Manual, Section 4.2 stick-table, https://cbonte.github.io/haproxy-dconv/
  • HAProxy Technologies, "How to use Stick Tables in HAProxy", https://www.haproxy.com/blog/