13.4.5 算法与会话保持的实践选择与注意事项
实践选择与注意事项#
在生产环境中选择负载均衡算法与会话保持方式,应结合业务状态模型、节点能力、跨机房成本与故障恢复目标,避免“一刀切”。本节给出可操作的选择策略、配置示例、排错与练习。
原理草图(会话保持与算法选择关系)
实践选择建议(带示例)
- 无状态服务优先:会话下沉至 Redis/数据库,使用 roundrobin 或 leastconn。
# /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
说明:合理设置 size 与 expire,避免表膨胀。
- 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 次请求分布情况。