如何在 HAProxy 中实现基于 Cookie 的会话保持 stick-table?
核心结论:HAProxy 的 stick-table 每条记录平均占用 50-166 字节内存,支持最多 100 万条记录(size 1m),但需注意 stick-table 与 Cookie 是两种独立的会话保持机制,不能混用配置。
原因分析
很多用户混淆了 stick-table 和 Cookie 会话保持的概念。根据 2026 年 4 月 13 日的技术资料,stick-table 是 HAProxy 内存中维护客户端与后端 1:1 映射关系的键值表,支持 ip、header、cookie 等多维度标识提取,而 Cookie 插入是另一种独立机制。常见错误是只写 stick-table 却漏掉 stick on,结果表建了但完全不触发匹配。stick-table 的优势在于无状态后端 + 客户端无 cookie 支持 + 多维度关联,而 Cookie insert 依赖客户端存储和回传,一旦用户禁用 cookie、使用 CLI 工具调用 API,或后端返回 302 跳转丢失 cookie,就会断连。
解决方案
方案一:使用 stick-table 实现会话保持
在 backend 或 listen 块中显式声明 stick-table,且需搭配 stick on 才生效。配置示例(2026 年 3 月 31 日资料):
backend app
stick-table type ip size 10k expire 30m
stick on src
balance roundrobin
server web1 10.0.0.17:80 check按源 IP 绑定时,size 1m 表示最多存 100 万条记录,不是字节数。若提取 header 或 URL 参数,使用 stick-table type string len 64 size 100k expire 1h,len 64 必须≥实际值长度,否则截断导致误匹配。
方案二:使用 Cookie 插入实现会话保持
在 http 模式下配置(2026 年 1 月 25 日资料):
listen webcluster
bind *:80
balance roundrobin
cookie WEBCOOKIE insert nocache indirect
server haha 192.168.0.10:80 cookie web1 check inter 3s fall 3 rise 5 weight 2
server hehe 192.168.0.20:80 cookie web2 check inter 3s fall 3 rise 5 weight 1cookie insert 表示当后端响应中没有该 cookie 时,HAProxy 会插入名为 WEBCOOKIE 的 cookie。server 指令中的 cookie 值(如 web1、web2)用于标识该 server,HAProxy 会把该值写入客户端 cookie。
方案三:结合 JSESSIONID 的 StickyTable(Java 应用)
针对 Java 应用(2026 年 3 月 31 日资料),通过服务端生成的 session ID(如 JSESSIONID)查表匹配后端服务器:
backend java_app
stick-table type string len 64 size 100k expire 1h
stick on req.cook(JSESSIONID)
stick store-response
server tomcat1 192.168.1.10:8080 check
server tomcat2 192.168.1.11:8080 checkJava 应用需确保 Session ID 可被 HAProxy 提取,默认使用 JSESSIONID Cookie,且响应中需携带 Set-Cookie,首次请求返回 200 时应用必须设置 Set-Cookie: JSESSIONID=xxx,HAProxy 才能通过 stick store-response 捕获并写入表。
注意事项
1. stick-table 只对当前作用域(backend/listen)有效,跨 scope 不共享,不要在 frontend 中定义 stick-table 后直接 use_backend 跳转(2026 年 4 月 13 日资料)。
2. 调试 stick-table 是否生效的三个实操步骤:通过 Socket 接口实时查询 echo "show table app" | socat stdio /var/run/haproxy.sock,检查表中条目是否随请求更新(2025 年 6 月 2 日资料)。
3. Cookie 会话保持不支持 tcp mode,必须使用 http mode,且基于 Cookie 的会话保持会增加 HAProxy 负载,高并发场景建议改用会话共享服务器(如 Redis)(2025 年 6 月 2 日资料)。
4. 粘性表溢出处理:增大 stick-table size 或缩短 expire 时间,每条 stickiness 记录占用空间平均最小 50 字节,最大 166 字节(2024 年 9 月 26 日资料)。
5. NAT 环境下客户端 IP 可能变化导致基于 source 的会话保持失效,建议使用 Cookie 或 stick-table 结合 header 提取更稳定的标识。
参考来源
来源:HAProxy 技术博客 - 怎么在 HAProxy 中利用 Stick-Table 实现用户会话的保持(2026 年 4 月 13 日)
来源:Java 应用会话保持指南 - HAProxy 中 StickyTable 实现 Java 应用高级会话保持(2026 年 3 月 31 日)
来源:HAProxy 配置实战 - Haproxy 会话保持:基于 Cookie 优化(2026 年 1 月 25 日)
来源:HAProxy 调试手册 - 如何调试 HAProxy 的会话保持配置(2025 年 6 月 2 日)