Tomcat Session 管理与分布式方案
Tomcat Session 管理与分布式方案
1. 引言
在 Web 应用中,HTTP 协议是无状态的,为了识别用户会话,Tomcat 提供了 Session 管理机制。
在单机应用中,Session 存放在内存中即可,但在 分布式集群部署 时,Session 必须能够在多个 Tomcat 节点之间共享或复制。
本篇文章我们将深入剖析:
- Tomcat 的 Session 生命周期管理
- Session 的持久化与存储机制
- 分布式集群下的 Session 复制方案(DeltaManager、BackupManager)
- 结合源码,揭开 Tomcat Session 高可用的实现原理
2. Session 管理体系结构
在 Tomcat 中,Session 管理由 Manager
组件负责,主要包括:
-
StandardManager
- 默认实现
- Session 存储在内存中
- 可选择持久化到磁盘
-
PersistentManager
- 在空闲时将 Session 持久化到磁盘
- 减少内存压力
-
DeltaManager(集群环境)
- 集群模式下的 Session 同步方案
- 每次 Session 更新都会广播给集群中的其他节点
-
BackupManager(优化方案)
- Session 只同步到一台备份节点
- 相比 DeltaManager,减少网络开销
👉 架构图:
Session└── Manager(管理器)├── StandardManager(单机内存管理)├── PersistentManager(持久化)└── ClusterManager(集群)├── DeltaManager(全量复制)└── BackupManager(单点备份)
3. Session 生命周期
-
创建
- 首次请求时,若没有
JSESSIONID
,Tomcat 会新建 Session - 生成唯一 ID(默认使用
SecureRandom
)
- 首次请求时,若没有
-
使用
- 通过
HttpSession.setAttribute()
存储数据 - 每次请求更新
lastAccessedTime
- 通过
-
过期
- 超过
maxInactiveInterval
(默认 30 分钟)未访问,会被销毁
- 超过
-
销毁
- Session 超时或应用关闭时销毁
- 调用
HttpSessionListener.sessionDestroyed()
4. 核心源码解析
(1) Session 接口
public interface Session {String getId();long getCreationTime();Object getAttribute(String name);void setAttribute(String name, Object value);void invalidate();
}
(2) StandardSession(标准实现)
public class StandardSession implements Session, HttpSession {private String id;private Map<String,Object> attributes = new HashMap<>();private long lastAccessedTime;private int maxInactiveInterval;@Overridepublic void setAttribute(String name, Object value) {attributes.put(name, value);}@Overridepublic void invalidate() {attributes.clear();// 触发 SessionListener 销毁事件}
}
(3) StandardManager(单机内存管理)
public class StandardManager extends ManagerBase {@Overridepublic Session createSession(String sessionId) {StandardSession session = new StandardSession(this);session.setNew(true);session.setId(sessionId);return session;}@Overridepublic void load() {// 从磁盘反序列化 Session}@Overridepublic void unload() {// 将 Session 持久化到磁盘}
}
(4) DeltaManager(集群模式)
public class DeltaManager extends ClusterManagerBase {@Overridepublic void send(Session session) {// 将 Session 状态序列化// 通过集群通道(ClusterChannel)广播给所有节点}@Overridepublic void messageReceived(ClusterMessage msg) {// 接收其他节点的 Session 更新// 应用到本地 SessionMap}
}
👉 特点:所有节点都保存完整 Session 副本,同步开销大。
(5) BackupManager(优化方案)
public class BackupManager extends ClusterManagerBase {@Overridepublic void send(Session session) {// 将 Session 同步到一个备份节点}
}
👉 特点:降低广播压力,但可靠性依赖于单一备份。
5. Session 在请求中的处理流程
1. Request 进入 Context
2. StandardContextValve 检查 Cookie/JSESSIONID
3. 若存在 JSESSIONID → 从 Manager 中查找 Session
4. 若不存在 → 创建新 Session
5. 请求结束时 → 更新 Session 最后访问时间
6. 若配置了集群 → 触发 Manager 的 send() 方法广播更新
6. Session 集群配置
在 server.xml
中启用集群:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"managerClassName="org.apache.catalina.ha.session.DeltaManager"channelSendOptions="8"><Manager className="org.apache.catalina.ha.session.DeltaManager"expireSessionsOnShutdown="false"notifyListenersOnReplication="true"/><Channel className="org.apache.catalina.tribes.group.GroupChannel"/>
</Cluster>
7. 分布式 Session 的替代方案
由于 Tomcat 的集群 Session 复制存在性能瓶颈,生产中常用以下替代方案:
-
粘性会话(Sticky Session)
- 负载均衡器(如 Nginx)将同一用户的请求路由到同一个 Tomcat 节点
- 不需要复制 Session
- 缺点:节点宕机会丢失 Session
-
外部存储
- 将 Session 存储到 Redis、数据库
- 所有节点共享 Session 存储
- 高可用性强,现代架构中最常见
8. 总结
本篇文章深入剖析了 Tomcat Session 管理与分布式方案:
- Session 生命周期:创建 → 使用 → 过期 → 销毁
- Manager 实现:StandardManager、PersistentManager、DeltaManager、BackupManager
- 集群模式:全量复制(DeltaManager) vs 单点备份(BackupManager)
- 源码解析:StandardSession、StandardManager、DeltaManager
- 替代方案:Sticky Session / Redis
这样,我们就完整掌握了 Tomcat Session 高可用与分布式管理机制。