概要
Session活化:从硬盘上读取序列化的session到内存中
Session钝化:把内存中的session序列化到硬盘上
Tomcat中两种Session钝化管理器
session钝化机制是由sessionManager管理
tomcat提供了以下这两种session处理方式
org.apache.catalina.session.StandarManager
org.apache.catalina.session.Persistentmanager
StandarManager是tomcat的session默认处理方式,如果配置Persistentmanager则使用Persistentmanager,没有配置则使用StandarManager。
1. StandarManager
当Tomcat服务器关闭或者重启时tomcat服务器会将当前内存中的session对象钝化到服务器文件系统中;
另一种情况是web应用程序被重新加载时(其实原理也是重启tomcat),内存中的session对象也会被钝化到服务器的文件系统中
当系统启动时,会把序列化到硬盘上session重新加载到内存中来。这样用户还保持这登录状态,提供系统的可用性。
- 只有在tomcat关闭和启动的时候才会活化和钝化session
- 强制kill掉tomcat是不会把session钝化到硬盘上的。
2. Persistentmanager
可以将内存中长时间不用的session钝化到硬盘上,减少内存的占用。
比如:当网站有大量用户访问的时候,服务器会创建大量的session,会占用大量的服务器内存资源,当用户开着浏览器一分钟不操作页面的话建议将session钝化,将session生成文件放在tomcat工作目录下。
那怎么该设置呢?
在 /WebRoot/META-INF 目录下创建 context.xml文件(也可以在tomca目录下的其他四个地方创建,在这里建是为了只对这个网站起作用),配置如下:
<?xml version="1.0" ?>
<Context>
<Manager className="org.apache.catalina.session.PersistentManager"
maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore"
directory="sessionDir" />
</Manager>
</Context>
StandarManager 源码分析
Session活化 doLoad() 方法
在当前程序重新启动的时候,调用doLoad() 方法进行活化session
- 清空sessions中的session(刚启动,sessions中应该是没有session的)
protected Map<String, Session> sessions = new ConcurrentHashMap<>();
- 判断是否有钝化的session文件。如果没有则结束加载session,如果有文件,则进行下面的加载session
- 获取当前项目的WebappClassLoader
- 从硬盘中读取session,并把session反序列化成StandardSession对象。然后激活当前的session,并判断当前session是否过期
activate() 方法
这个方法迭代执行了所有在web.xml中注册的session活化的listener监听器。
expire() 方法
expire方法是判断session是否过期,如果过期则执行所有在web.xml中注册过所有的HttpSessionListener的sessionDestroyed()方法
Session钝化 unLoad() 方法
在当前程序关闭的时候,调用unLoad() 方法进行钝化session
- 获取输出文件流
- 遍历内存中所有的session,并把session序列化到硬盘文件中。
- 把序列化过的session置为不可用,并重置session中的所有属性。
PersistentManager 源码分析
1. session 钝化
通过 ContainerBase.startInternal() -> threadStart() 开启一个线程,定时的轮询所有的session,把长时间不使用(或者超出最大数量等)的session钝化到硬盘上。
threadStart()
每隔backgroupProcessorDelay时间轮询处理session。
processPersistenceChecks()
PersistentManagerBase.processExpires() -> processPersistenceChecks()
Tomcat只是在下面三种情况会将Session通过Store保存起来:
- 当Session的空闲时间超过minIdleSwap和maxIdleSwap时,会将Session换出
- 当Session的空闲时间超过maxIdleBackup时,会将Session备份出去
- 当Session总数大于maxActiveSession时,会将超出部分的空闲Session换出
下面只分析下第一种情况的源码processMaxIdleSwaps() 方法
processMaxIdleSwaps()
- 判断Session的空闲时间超过minIdleSwap和maxIdleSwap值。
- 如果超过则通过 swapOut() 方法把session钝化到硬盘上。
swapOut() 方法
- 通过passivate() 方法调用web.xml 中注册的HttpSessionActivationListener事件(同StandardSession)
- 调用writeSession() 方法把session钝化到指定的地方
- 从sessions 中把session移除
- 重置session,等待垃圾收集器回收此session。
writeSession()
调用store把session存储到指定的地方,如下面的配置,是把session钝化到硬盘文件中。
<Store className="org.apache.catalina.session.FileStore" directory="sessionDir" />
2. session 活化
- 当请求中获取session时,先从调用findSession() 从内存sessions 中查找。
- 如果内存中找不到 则调用 swapIn() 方法,进行查找,判断该session是否钝化了,如果钝化则把该session活化加载到内存。
swapIn() 方法
为当前查找的session设置一个lock。
- 双重检查,在锁中再次判断sessions中是否有此session。
- 从store中加载session。
- 如果store 有此session 并判断该session是否过期,并做处理
- 通过tellNew() 调用 web.xml 中注册HttpSessionListener的事件
- 把session添加到sessions 集合中。
- 通过activate()方法调用web.xml中注册的HttpSessionActivationListener事件
- 最后把该session相关的锁,删除。
想了解更多精彩内容请关注我的公众号
网友评论