要实现apache负载均衡的会话粘性,关键是配置stickysession并确保balancermember显式声明route参数,同时让apache识别并信任含route后缀的cookie(如jsessionid.web1)或主动注入routeid cookie。

要让 Apache 代理在负载均衡中把同一用户始终发给同一台后端服务器,关键不是“开启粘性”,而是让 Apache 能识别并信任某个 Cookie 值,并把它和后端节点的 route 标识对应起来。默认情况下它完全不看 Cookie,必须手动配对。
加载必要模块
确保以下四个模块已启用(检查 httpd.conf 或运行 httpd -M | grep proxy):
- mod_proxy.so:反向代理基础
- mod_proxy_balancer.so:定义集群和负载策略
- mod_proxy_http.so(或 mod_proxy_ajp.so):与后端通信协议
- mod_headers.so(推荐):用于主动写入路由 Cookie,增强可靠性
定义带 route 的后端集群
每个 BalancerMember 必须显式声明 route 参数,且值要和后端服务实际输出的路由标识完全一致(大小写敏感):
<proxy balancer:> BalancerMember http://192.168.1.10:8080 route=web1 BalancerMember http://192.168.1.11:8080 route=web2 </proxy>
注意:
– 不写 route,Apache 就无法匹配 Cookie 中的后缀,粘性必然失效;
– route 值不能重复,也不能留空;
– 若后端是 Tomcat,需在 server.xml 的
启用 stickysession 并指定 Cookie 名
在 ProxyPass 指令中加入 stickysession 参数,告诉 Apache 该盯住哪个 Cookie:
ProxyPass / balancer://myapp/ stickysession=JSESSIONID|jsessionid nofailover=Off ProxyPassReverse / balancer://myapp/
说明:
– JSESSIONID|jsessionid 表示兼容大小写变体,防止客户端或中间设备修改首字母;
– Apache 只提取 Cookie 值中 点号后的部分(如 abc123.web1 → 提取 web1),再去找 route=web1 的节点;
– nofailover=Off 允许节点宕机时自动切到其他健康节点(避免用户直接报错);设为 On 则强制绑定、不切换。
补充:用 ROUTEID 主动注入更可靠
如果后端不支持自动加 route 后缀(比如 PHP 或 Spring Boot 内嵌 Tomcat),可让 Apache 自己下发路由标识:
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; Path=/; HttpOnly; Secure" env=BALANCER_ROUTE_CHANGED
然后把 stickysession 改成:
stickysession=ROUTEID|JSESSIONID
这样首次请求分配节点后,Apache 会主动写入 ROUTEID=.web1,后续请求就靠这个 Cookie 维持粘性,不依赖后端是否规范输出 JSESSIONID。










