Apache实现会话粘性需配置stickysession绑定JSESSIONID等Cookie,并在BalancerMember中显式指定与Tomcat jvmRoute一致的route值,否则请求将轮询分发导致Session丢失。

Apache 本身不处理 Java 应用的 Session 数据,它只负责把请求“粘”到某个后端 Tomcat 节点上。真正的 Session 保持靠的是 stickysession + 后端 jvmRoute 配合,不是 Apache 自己存 Session。
stickysession=BALANCEID|ROUTEID 怎么选
Apache 的 mod_proxy_balancer 默认生成 BALANCEID Cookie(如 BALANCEID=balancer.1),但 Java 应用(尤其是 Tomcat)更习惯识别 ROUTEID 或 JSESSIONID 中带路由标识的格式。
-
stickysession=JSESSIONID最常用:前提是每个 Tomcat 的server.xml里已配了jvmRoute,比如,这样 Tomcat 返回的JSESSIONID就会变成ABC123.tomcat1 -
stickysession=ROUTEID需要 Apache 主动写 Cookie:配合mod_headers和环境变量,例如Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED -
stickysession=BALANCEID|ROUTEID是兜底写法:优先匹配BALANCEID,找不到再看ROUTEID;适合混合部署或灰度迁移场景
route= 参数为什么必须显式声明
Apache 不会自动把 JSESSIONID=xxx.tomcat1 中的 tomcat1 映射到对应后端——它需要你明确告诉它:“tomcat1 对应哪个 BalancerMember”。
- 每个
BalancerMember必须带route=xxx,且值要和 Tomcat 的jvmRoute完全一致(大小写敏感) - 如果漏写
route,即使 Cookie 正确,Apache 也识别不了,请求仍会轮询分发 - 错误示例:
BalancerMember http://192.168.1.10:8080缺 route → 粘性失效 - 正确写法:
BalancerMember http://192.168.1.10:8080 route=tomcat1
HTTPS 下 Secure 和 HttpOnly 标志不能少
生产环境若忽略 Cookie 安全属性,浏览器可能拒绝发送 JSESSIONID,导致每次请求都被重新分配,看起来“粘性失效”。
审查 Remix v2 代码中的 v1 形态 meta 导出(v2 中为破坏性变更),cookie 安全漏洞(httpOnly、secure、密钥轮换),认证门位于错误层级,以及其他
- Apache 不会自动给后端返回的
JSESSIONID加Secure或HttpOnly;这些得由 Tomcat 控制(通过context.xml的sessionCookieSecure="true"和sessionCookieHttpOnly="true") - 如果用
ROUTEID方式,Apache 用Header add Set-Cookie写 Cookie 时,必须手动加Secure; HttpOnly,例如:Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/; Secure; HttpOnly" - HTTP 站点不要设
Secure,否则 Cookie 不会被携带;开发环境建议统一走 HTTPS
后端节点宕机时粘性会断,这不是配置问题
这是粘性 Session 的固有缺陷:Apache 发现某 route=tomcat1 的节点健康检查失败,就会把它从可用列表中剔除。此时客户端再带着 JSESSIONID=xxx.tomcat1 请求过来,Apache 找不到对应成员,只能重新分配——Session 丢失。
- 这不是
stickysession配错,而是设计如此 - 单靠 Apache 粘性无法解决故障转移,必须搭配后端 Session 共享(如 Redis 存储)或 Session 复制(Tomcat cluster)
- 临时缓解可加
nofailover=On,但会导致请求直接 503,不推荐生产使用 - 真正健壮的方案是:粘性用于日常负载均衡 + 后端 Session 持久化兜底
最易被忽略的一点:Apache 的 stickysession 只解析 Cookie 值,不校验格式合法性。如果 Tomcat 返回的 JSESSIONID 里路由部分含非法字符(如点号后多了一个空格),Apache 就匹配不上 route,整个粘性链路就断了——查日志时注意看 error_log 里有没有 “no route found for session ID” 类提示。










