深入剖析Tomcat会话机制
1缓存机制
Tomcat默认将Session保存到内存中。但同时,Tomcat也提供了PersistentManager配合不同的Store实现的方式,使Session可以被保存到不同地方(Database,Redis,Memcached等)。
例如下面的配置:
ManagerBase 实现了Manager接口的backgroundProcess()方法。在ManagerBase.backgroundProcess()中调用子类PersistentManagerBase.processExpire()。在processExpire()中会对前面提到的Session被持久化的三种情况进行处理。下面就来看下这三种情况的源码。
2.3换出和备份
先以情况1换出空闲时间过长的Session的源码为例。
public void save(Session session) throwsIOException { Jedis jedis = null; Boolean error = true; try { log.trace("Saving session " +session + " into Redis"); RedisSession redisSession =(RedisSession) session; if (log.isTraceEnabled()) { log.trace("Session Contents[" + redisSession.getId() + "]:"); Enumeration en =redisSession.getAttributeNames(); while(en.hasMoreElements()) { log.trace(" " + en.nextElement()); } } Boolean sessionIsDirty =redisSession.isDirty(); redisSession.resetDirtyTracking(); byte[] binaryId =redisSession.getId().getBytes(); jedis = acquireConnection(); Boolean isCurrentSessionPersisted =this.currentSessionIsPersisted.get(); if (sessionIsDirty ||(isCurrentSessionPersisted == null || !isCurrentSessionPersisted)) { jedis.set(binaryId, serializer.serializeFrom(redisSession)); } currentSessionIsPersisted.set(true); log.trace("Setting expire timeout onsession [" + redisSession.getId() + "] to " +getMaxInactiveInterval()); jedis.expire(binaryId,getMaxInactiveInterval()); error = false; } catch (IOException e) { log.error(e.getMessage()); throw e; } finally { if (jedis != null) { returnConnection(jedis, error); } } }参考资料
1 tomcat-redis-session-manager官网
https://github.com/jcoleman/tomcat-redis-session-manager
2《深入剖析Tomcat》