13.4.3 会话保持机制与实现方式
会话保持用于将同一客户端的连续请求定向到同一后端,避免状态不一致或重复登录。HAProxy常见实现方式包括基于源地址、基于Cookie/应用会话标识以及基于Stick Table的持久化策略。下面给出原理草图、可执行配置与验证命令。
原理草图(HTTP Cookie 与 Stick Table):
最小可执行示例(HTTP 会话保持,含 Cookie 与 Stick Table):
# /etc/haproxy/haproxy.cfg
global
log /dev/log local0
maxconn 20000
defaults
mode http
log global
timeout connect 5s
timeout client 30s
timeout server 30s
frontend fe_web
bind *:80
# 方式1:基于应用Cookie名 sessionid
stick-table type string len 64 size 100k expire 30m
stick on req.cook(sessionid)
default_backend be_web
backend be_web
balance roundrobin
# 方式2:HAProxy插入Cookie实现粘性
cookie SRV insert indirect nocache
server srv1 10.0.0.11:8080 check cookie s1
server srv2 10.0.0.12:8080 check cookie s2
关键参数说明:
- stick-table:创建会话表,expire 30m表示30分钟无访问即失效。
- stick on req.cook(sessionid):以应用Cookie为键进行保持。
- cookie SRV insert:HAProxy插入名为SRV的Cookie;indirect避免转发给后端,nocache避免缓存污染。
TCP 会话保持(适用于 MySQL/Redis 等长连接):
# /etc/haproxy/haproxy.cfg
defaults
mode tcp
timeout connect 5s
timeout client 1m
timeout server 1m
frontend fe_db
bind *:3306
default_backend be_db
backend be_db
balance source
# 或使用 stick-table:
# stick-table type ip size 50k expire 1h
# stick on src
server db1 10.0.0.21:3306 check
server db2 10.0.0.22:3306 check
关键参数说明:
- balance source:按源IP保持,适合客户端IP稳定场景。
- stick on src:以源IP为键,灵活扩展统计字段。
安装与启用(以 Debian/Ubuntu 为例):
# 安装
sudo apt-get update
sudo apt-get install -y haproxy
# 验证配置语法
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# 启动并设置开机自启
sudo systemctl enable --now haproxy
sudo systemctl status haproxy
预期效果:haproxy -c返回“Configuration file is valid”;systemctl status显示active (running)。
验证会话保持(HTTP 示例):
# 1) 首次请求,观察响应头Set-Cookie或应用Cookie
curl -I http://<VIP_OR_HAPROXY_IP>/ -c /tmp/cookie.txt
# 2) 携带Cookie再次请求,观察是否始终命中同一后端
for i in {1..5}; do
curl -s http://<VIP_OR_HAPROXY_IP>/ -b /tmp/cookie.txt | head -n 1
done
预期效果:后端应用可在响应中打印服务器标识,连续请求命中同一节点。
排错思路与命令:
# 1) 查看HAProxy日志,确认粘性是否命中
sudo tail -f /var/log/haproxy.log
# 2) 查看会话表统计(需开启stats socket)
# 配置:stats socket /run/haproxy/admin.sock mode 660 level admin
echo "show table" | sudo socat /run/haproxy/admin.sock stdio
# 3) 配置检查失败常见原因
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
# 关注:stick-table长度、cookie名拼写、mode tcp/http一致
常见问题:
- 应用未设置sessionid:改用cookie SRV insert或检查应用端Cookie。
- 多层代理/NAT导致源IP变化:避免balance source,改用Cookie或应用会话标识。
- 粘性过长导致热点:调小expire或采用无状态设计。
练习:
1. 在HTTP示例中,将expire 30m改为5m,观察会话失效后的后端切换行为。
2. 将balance roundrobin改为leastconn,对比在高并发下的后端分配。
3. 为be_web新增第三台后端,验证Cookie插入后是否稳定命中同一实例。