backgroundProcessorDelay默认值是10,也就是每10秒检测一次,然后调用Container的backgroundProcess方法,此方法又调用Manager里面的backgroundProcess:
public void backgroundProcess() {
count = (count + 1) % processExpiresFrequency;
if (count == 0)
processExpires();
}
/**
* Invalidate all sessions that have expired.
*/
public void processExpires() {
long timeNow = System.currentTimeMillis();
Session sessions[] = findSessions();
int expireHere = 0 ;
if(log.isDebugEnabled())
log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
if (sessions[i]!=null && !sessions[i].isValid()) {
expireHere++;
}
}
long timeEnd = System.currentTimeMillis();
if(log.isDebugEnabled())
log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow );
}
processExpiresFrequency默认值是6,那其实最后就是6*10=60秒执行一次processExpires,具体如何检测过期在session的isValid方法中:
public boolean isValid() {
if (!this.isValid) {
return false;
}
if (this.expiring) {
return true;
}
if (ACTIVITY_CHECK && accessCount.get() > 0) {
return true;
}
if (maxInactiveInterval > 0) {
long timeNow = System.currentTimeMillis();
int timeIdle;
if (LAST_ACCESS_AT_START) {
timeIdle = (int) ((timeNow - lastAccessedTime) / 1000L);
} else {
timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
}
if (timeIdle >= maxInactiveInterval) {
expire(true);
}
}
return this.isValid;
}
主要是通过对比当前时间到上次活跃的时间是否超过了maxInactiveInterval,如果超过了就做expire处理;
Redis集中式管理Session分析
在上文中使用tomcat-redis-session-manager来管理session,下面来分析一下是如果通过redis来集中式管理Session的;围绕session如何获取,如何创建,何时更新到redis,以及何时被移除;
1.如何获取
RedisSessionManager重写了findSession方法
public Session findSession(String id) throws IOException {
RedisSession session = null;
if (null == id) {
currentSessionIsPersisted.set(false);
currentSession.set(null);
currentSessionSerializationMetadata.set(null);
currentSessionId.set(null);
} else if (id.equals(currentSessionId.get())) {
session = currentSession.get();
} else {
byte[] data = loadSessionDataFromRedis(id);
if (data != null) {
DeserializedSessionContainer container = sessionFromSerializedData(id, data);
session = container.session;
currentSession.set(session);
currentSessionSerializationMetadata.set(container.metadata);
currentSessionIsPersisted.set(true);
currentSessionId.set(id);
} else {
currentSessionIsPersisted.set(false);
currentSession.set(null);
currentSessionSerializationMetadata.set(null);
currentSessionId.set(null);
}
}









