应采用Redis外置Session实现分布式会话共享,并辅以Apache粘性会话优化首字节响应;需对齐sessionTimeout与Redis过期时间,禁用IP_HASH,配合graceful重启与健康检查保障平滑过渡。
集群节点重启导致会话失效,本质是本地 session 被清空,而其他节点又无法获取该用户的历史会话状态。这不是“配置没加对”的问题,而是架构层面必须解决的状态外置需求。核心思路是:**不让会话依赖单节点内存,改由共享存储统一托管**。
用 Redis 实现分布式会话共享
这是最成熟、低侵入、高可用的方案,尤其适合 Tomcat + Apache 组合(Apache 作反向代理,Tomcat 集群承载业务):
- 在所有 Tomcat 节点上集成 tomcat-cluster-redis-session-manager 4.0 模块,它会自动拦截 Session 的 create/get/setAttribute/remove 等操作,将数据序列化后存入 Redis
- 无需修改业务代码,Servlet 规范兼容,
request.getSession()行为完全不变 - Redis 自身支持主从+哨兵或 Cluster 模式,单点故障不影响会话读写;节点重启后,新请求仍能通过 Session ID 找回原有会话
- 注意配置
sessionTimeout与 Redis key 过期时间对齐(如设为 30 分钟),避免内存中 Session 已过期但 Redis 里还残留
启用 Apache 层的粘性会话(Sticky Session)作为补充
即使用了 Redis,粘性会话仍有价值——它能减少跨节点的 Session 查找开销,提升首字节响应速度:
- 在 Apache 的
mod_proxy_balancer中启用stickysession=ROUTEID,配合后端 Tomcat 在响应头中注入Set-Cookie: ROUTEID=12345 - 或使用更稳定的
stickysession=JSESSIONID|Path=/(前提是 Tomcat 的context.xml中sessionCookiePath="/"已设置) - 关键点:粘性只是“路由偏好”,不是强绑定;当某节点宕机或重启,负载均衡器会自动把流量切到健康节点,而 Redis 保证了会话数据可立即访问
避免依赖 IP_HASH 或客户端 IP 做会话保持
在云环境或有前置 LB(如 AWS ALB、阿里云 SLB)时,IP_HASH 几乎必然失效:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 云 LB 默认做四层转发,后端 Apache 收到的源 IP 是 LB 的内网地址,所有请求哈希结果一致,流量全打到同一台
- 即便在纯 Apache 环境下,NAT、代理、移动网络也会导致同一用户 IP 频繁变化,破坏会话连续性
- 不推荐用客户端 IP 做唯一标识——它不稳定、不可控、且存在隐私合规风险
节点重启期间的平滑过渡要点
哪怕用了 Redis,也要防止重启瞬间出现 502 或会话错乱:
- Apache 启用
graceful重启(apachectl graceful),确保旧连接处理完再退出,不中断正在传输的响应 - Tomcat 配置
unloadDelay="60000"(单位毫秒),让关闭前等待 1 分钟,尽量完成未提交的 Session 写入 Redis - 健康检查路径(如
/health)应包含 Redis 连通性校验,Apache 的ProxyHCExpr只有确认后端真正就绪才恢复流量









