下面谈一谈Session的管理。
一. Session的管理
当tomcat启动时,会开启一个后台线程,这个后台线程是随容器的启动而启动的,它将定期检查会话超时。
(org.apache.catalina.core.ContainerBase.threadStart())
protected void threadStart() {
if (thread != null)
return;
//
if (backgroundProcessorDelay <= 0)
return;
threadDone = false;
String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
thread = new Thread(new ContainerBackgroundProcessor(), threadName);
thread.setDaemon(true);
thread.start();
}
1.此时会新建一个ContainerBackgroundProcessor线程。
(org.apache.catalina.core.ContainerBase.ContainerBackgroundProcessor)
protected class ContainerBackgroundProcessor implements Runnable {
public void run() {
while (!threadDone) {
try {
Thread.sleep(backgroundProcessorDelay * 1000L);
} catch (InterruptedException e) {
;
}
if (!threadDone) {
Container parent = (Container) getMappingObject();
ClassLoader cl =
Thread.currentThread().getContextClassLoader();
if (parent.getLoader() != null) {
cl = parent.getLoader().getClassLoader();
}
processChildren(parent, cl);//parent为StandardEngine
}
}
}
2.processChildren(parent,cl)--->processChildren(StandardHost,cl) --->processChildren(StandardContext,cl),最后StandardContext#backgroundProcess()方法被调用。
(org.apache.catalina.core.StandardContext.backgroundProcess())
public void backgroundProcess() {
if (!started)
return;
count = (count + 1) % managerChecksFrequency;
if ((getManager() != null) && (count == 0)) {
try {
getManager().backgroundProcess();
} catch ( Exception x ) {
log.warn("Unable to perform background process on manager",x);
}
}
3. StandardManager#processExpires()方法被调用。
org.apache.catalina.session.StandardManager.backgroundProcess()
public void backgroundProcess() {
processExpires();
}
4. StandardManager#processExpires()被调用,通过调用session#isValid()方法判断session是否有效,如果session无效将被销毁。
(org.apache.catalina.session.StandardManager.processExpires())
/**
* 处理所有已失效的session
*/
public void processExpires() {
long timeNow = System.currentTimeMillis();
Session sessions[] = findSessions();
for (int i = 0; i < sessions.length; i++) {
StandardSession session = (StandardSession) sessions[i];
if (!session.isValid()) {
expiredSessions++;
}
}
long timeEnd = System.currentTimeMillis();
processingTime += ( timeEnd - timeNow );
}
5.StandardSession#isValid()最终调用expire(true),然后返回isValid()的布尔值。
(org.apache.catalina.session.StandardSession.isValid())
public boolean isValid() {
if (this.expiring) {
return true;
}
if (!this.isValid ) {
return false;
}
if (accessCount > 0) {
return true;
}
if (maxInactiveInterval >= 0) {
long timeNow = System.currentTimeMillis();
int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
if (timeIdle >= maxInactiveInterval) {
expire(true);※3
}
}
return (this.isValid);
}
※3
StandardSession.expire()方法被调用,session被销毁。
(org.apache.catalina.session.StandardSession.expire(boolean notify))
public void expire(boolean notify) {
if (expiring)
return;
synchronized (this) {
if (manager == null)
return;
expiring = true;
//唤醒相关的应用程序事件监听者
Context context = (Context) manager.getContainer();
Object listeners[] = context.getApplicationLifecycleListeners();
if (notify && (listeners != null)) {
HttpSessionEvent event =
new HttpSessionEvent(getSession());
for (int i = 0; i < listeners.length; i++) {
int j = (listeners.length - 1) - i;
if (!(listeners[j] instanceof HttpSessionListener))
continue;
HttpSessionListener listener =
(HttpSessionListener) listeners[j];
try {
fireContainerEvent(context,
"beforeSessionDestroyed",
listener);
listener.sessionDestroyed(event);
fireContainerEvent(context,
"afterSessionDestroyed",
listener);
} catch (Throwable t) {
try {
fireContainerEvent(context,
"afterSessionDestroyed",
listener);
} catch (Exception e) {
;
}
manager.getContainer().getLogger().error
(sm.getString("standardSession.sessionEvent"), t);
}
}
}
accessCount = 0;
setValid(false);
// Remove this session from our manager's active sessions
if (manager != null)
manager.remove(this);
//唤醒相关的session事件监听者
if (notify) {
fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null);
}
// 处理完毕后,设置expiring为false
expiring = false;
//解除任何与此相关的session对象的绑定
String keys[] = keys();
for (int i = 0; i < keys.length; i++)
removeAttributeInternal(keys[i], notify);
}
}
分享到:
相关推荐
《深入解析Tomcat-Redis-Session-Manager源码》 在现代Web应用中,服务器端会话管理是一个至关重要的部分,特别是在高并发、分布式环境中。Tomcat作为最流行的Java Servlet容器,提供了丰富的功能来支持这一需求。...
描述中提到的“修改了tomcat-redis-session-manager源码进行的编译生成的jar包”,意味着这个jar包不是官方发布的原版,而是经过开发者对源代码进行了一些定制化的修改后重新编译得到的。这样的修改可能包括修复已知...
这个包里含有commons-pool2-2.4.2、jedis-2.9.0、tomcat85-session-redis-1.0三个主要JAR包。apache-tomcat-8.5.20.tar.gz源码包和context.xml文件,这套配置是我自己亲测可用的。。另外我用的redis4这个版本。注意...
自己通过源码编译后的jar包,已实验可以正常使用
因tomcat7使用redis共享session,其他的包存在问题,自己编译后处理通过。 该包是在https://github.com/jcoleman/tomcat-redis-session-manager 将源码编译后的包。
tomcat8下 tomcat-redis-session-manager , github上有源码,其他版本都有打好的jar包,tomcat 8 下没有,下载源码生成了一个。
"tomcat-redis-session-manager-master" 是一个项目名称,表明这是一个与Tomcat(一个流行的Java应用服务器)和Redis(一个开源的内存数据结构存储系统)相关的session管理器的主分支。通常,这样的项目是用来实现将...
本文将围绕“tomcat-redis-session-manager-master.zip”这个压缩包中的源码,深入探讨如何使用Redis实现Tomcat的session共享,并提供详尽的知识点解析。 首先,我们要理解Tomcat的session管理基础。在默认情况下,...
《深入理解Tomcat源码与Servlet-API》 ...综上所述,深入研究Tomcat源码和Servlet-API不仅能提升我们的开发技能,还能帮助我们更好地理解和优化Java Web应用的性能,从而在实际工作中发挥更大的价值。
2. **添加依赖**:在Tomcat的`lib`目录下,添加与Redis相关的Java库,例如`spring-session-data-redis`或`jedis`。压缩包中的jar文件可能包含了这些库。 3. **配置Tomcat**:在`$CATALINA_HOME/conf/context.xml`或...
综上所述,"Tomcat Redis Session"是一种在分布式环境中保证用户会话一致性的解决方案,通过集成Redis和Nginx,有效地解决了Web应用集群中的Session管理难题。在实际部署中,还需要考虑系统整体架构、性能优化和运维...
本文将围绕"tomcat-redis-session-manager"这一插件,详细探讨它如何支持Tomcat7,以及其源码和使用方法。 首先,"tomcat-redis-session-manager"是专为Tomcat设计的一个session管理器,用于将Tomcat的session数据...
Tomcat集群Redis会话管理器 Redis会话管理器是可插入的。 它将会话存储到Redis中,以便在Tomcat服务器群集之间轻松分配HTTP请求。 在这里,会话被实现为非粘性的(意味着,每个请求都可以转到集群中的任何服务器,...
描述提到的是一个基于"tomcat-redis-session-manager"源码编译生成的jar包,这意味着开发者或系统管理员可以直接将这个jar包引入到他们的Tomcat环境中,无需自己从源代码构建。压缩包内包含了针对Tomcat7和Tomcat8两...
Apache Tomcat 8.5.23 源码分析 Apache Tomcat 是一个开源的、免费的Web服务器和Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,...因此,对Tomcat源码的学习对于Java Web开发者来说是至关重要的。
6. **Session管理**:Tomcat如何实现session的创建、持久化、复制和过期策略。 7. **国际化与本地化**:Tomcat如何处理不同语言和地区的资源文件,提供多语言支持。 8. **WebSocket支持**:从Tomcat 7开始,Tomcat...
通过阅读和分析Tomcat源码,我们可以学习到以下知识点: 1. **Servlet生命周期**:Tomcat如何加载、初始化、服务、销毁Servlet,以及ServletConfig和ServletContext的角色。 2. **线程池管理**:Tomcat如何使用...
接下来,我们关注`tomcat-redis-session-manager-master-8.0`、`tomcat-redis-session-manager-master-8.5`和`tomcat-redis-session-manager-master-9`这些文件夹。它们分别对应Tomcat 8.0、8.5和9.0版本的`Tomcat-...