apache不管理java web应用session,仅作负载均衡;会话保持需结合sticky session与后端session复制或集中式存储(如redis)实现高可用。
apache 本身不管理 java web 应用的 session,它只是前端负载均衡器。所谓“会话保持”,本质是让同一个用户的请求始终路由到后端同一台 tomcat(或其它应用服务器),同时确保该用户登录状态在节点故障时仍可延续。单纯靠 apache 配置无法解决登录失效问题,必须结合后端 session 管理策略协同实现。
启用 sticky session(会话粘性)
这是最常用、见效最快的方案,适用于多数中小型集群:
- 使用 mod_proxy_balancer 时,在 ProxyPass 指令中添加
stickysession=JSESSIONID|jsessionid,并确保 route 参数能从 Cookie 或 URL 中正确提取 - 使用 mod_jk 时,在
workers.properties中为每个 worker 明确指定route值(如worker.tomcat1.route=tomcat1),该值需与 Tomcat 的jvmRoute完全一致 - Apache 会自动识别 JSESSIONID Cookie 中的 route 后缀(如
JSESSIONID=ABC123.tomcat1),并将后续请求固定转发至对应节点
配合 Tomcat session 复制保障高可用
仅靠粘性无法应对节点宕机——用户原节点挂了,新请求会被路由到其他节点,但该节点没有 session 数据,导致登录态丢失。必须叠加 session 复制:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 在 Web 应用的
WEB-INF/web.xml中添加<distributable></distributable>标签,声明支持分布式部署 - 在 Tomcat 的
conf/server.xml中,于<engine></engine>或<host></host>内配置完整<cluster></cluster>,推荐使用BackupManager(只同步到一个备份节点,网络开销小) - 为每个 Tomcat 实例设置唯一
jvmRoute,例如:<engine name="Catalina" defaulthost="localhost" jvmroute="tomcat1"></engine> - 验证关键点:多播是否可达、IP 地址配置是否正确、session 中存储的对象是否全部实现了
java.io.Serializable
改用集中式 session 存储(推荐用于生产环境)
避免复制带来的网络和内存压力,适合节点动态伸缩、大流量场景:
-
Redis 方案:集成
tomcat-cluster-redis-session-manager,将 session 全部存入 Redis。Tomcat 启动时加载该 Manager,所有读写操作自动代理至 Redis,业务代码零修改 -
Memcached 方案:使用
memcached-session-manager(MSM),需在 Tomcat 的lib目录放入对应 JAR 包,并在context.xml中配置 Manager 类和 Memcached 服务地址 -
Shiro + 外部存储:若项目已用 Apache Shiro,可替换默认
SessionDAO,对接 Redis、ZooKeeper 或 Ignite,由 Shiro 统一接管 session 生命周期
注意事项与常见陷阱
很多问题不是配置没写,而是细节被忽略:
- Apache 和 Tomcat 的
route值必须严格一致,大小写敏感,且不能含特殊字符 - JSESSIONID Cookie 默认路径为
/,若应用部署在子路径(如/app),需在 Apache 中用ProxyPassReverseCookiePath重写 Cookie 路径 - HTTPS 环境下,Tomcat 若未配置
secure="true",JSESSIONID Cookie 可能不带Secure标志,导致浏览器拒绝发送 - 测试 session 是否真正共享,不能只看是否跳转成功,要模拟节点宕机:停掉当前处理节点,刷新页面,确认仍能访问受保护资源









