Tomcat 之 Session的活化和钝化 源码分析

概要

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重新加载到内存中来。这样用户还保持这登录状态,提供系统的可用性。

  1. 只有在tomcat关闭和启动的时候才会活化和钝化session
  2. 强制kill掉tomcat是不会把session钝化到硬盘上的。

2. Persistentmanager

可以将内存中长时间不用的session钝化到硬盘上,减少内存的占用。

比如:当网站有大量用户访问的时候,服务器会创建大量的session,会占用大量的服务器内存资源,当用户开着浏览器一分钟不操作页面的话建议将session钝化,将session生成文件放在tomcat工作目录下。

那怎么该设置呢?

在 /WebRoot/META-INF 目录下创建 context.xml文件(也可以在tomca目录下的其他四个地方创建,在这里建是为了只对这个网站起作用),配置如下:

  
  
      
          
      
  

StandarManager 源码分析

Session活化 doLoad() 方法

在当前程序重新启动的时候,调用doLoad() 方法进行活化session


Tomcat 之 Session的活化和钝化 源码分析_第1张图片
  1. 清空sessions中的session(刚启动,sessions中应该是没有session的)
protected Map sessions = new ConcurrentHashMap<>();
  1. 判断是否有钝化的session文件。如果没有则结束加载session,如果有文件,则进行下面的加载session
Tomcat 之 Session的活化和钝化 源码分析_第2张图片
  1. 获取当前项目的WebappClassLoader
  2. 从硬盘中读取session,并把session反序列化成StandardSession对象。然后激活当前的session,并判断当前session是否过期

activate() 方法

Tomcat 之 Session的活化和钝化 源码分析_第3张图片

这个方法迭代执行了所有在web.xml中注册的session活化的listener监听器。

expire() 方法

Tomcat 之 Session的活化和钝化 源码分析_第4张图片

expire方法是判断session是否过期,如果过期则执行所有在web.xml中注册过所有的HttpSessionListener的sessionDestroyed()方法

Session钝化 unLoad() 方法

在当前程序关闭的时候,调用unLoad() 方法进行钝化session

Tomcat 之 Session的活化和钝化 源码分析_第5张图片
  1. 获取输出文件流
  2. 遍历内存中所有的session,并把session序列化到硬盘文件中。
  3. 把序列化过的session置为不可用,并重置session中的所有属性。

PersistentManager 源码分析

1. session 钝化

通过 ContainerBase.startInternal() -> threadStart() 开启一个线程,定时的轮询所有的session,把长时间不使用(或者超出最大数量等)的session钝化到硬盘上。

threadStart()

Tomcat 之 Session的活化和钝化 源码分析_第6张图片
Tomcat 之 Session的活化和钝化 源码分析_第7张图片

每隔backgroupProcessorDelay时间轮询处理session。

processPersistenceChecks()

PersistentManagerBase.processExpires() -> processPersistenceChecks()


Tomcat 之 Session的活化和钝化 源码分析_第8张图片

Tomcat只是在下面三种情况会将Session通过Store保存起来:

  1. 当Session的空闲时间超过minIdleSwap和maxIdleSwap时,会将Session换出
  2. 当Session的空闲时间超过maxIdleBackup时,会将Session备份出去
  3. 当Session总数大于maxActiveSession时,会将超出部分的空闲Session换出

下面只分析下第一种情况的源码processMaxIdleSwaps() 方法

processMaxIdleSwaps()

Tomcat 之 Session的活化和钝化 源码分析_第9张图片
  1. 判断Session的空闲时间超过minIdleSwap和maxIdleSwap值。
  2. 如果超过则通过 swapOut() 方法把session钝化到硬盘上。

swapOut() 方法

Tomcat 之 Session的活化和钝化 源码分析_第10张图片
  1. 通过passivate() 方法调用web.xml 中注册的HttpSessionActivationListener事件(同StandardSession)
  2. 调用writeSession() 方法把session钝化到指定的地方
  3. 从sessions 中把session移除
  4. 重置session,等待垃圾收集器回收此session。

writeSession()

Tomcat 之 Session的活化和钝化 源码分析_第11张图片

调用store把session存储到指定的地方,如下面的配置,是把session钝化到硬盘文件中。

  

2. session 活化

Tomcat 之 Session的活化和钝化 源码分析_第12张图片
  1. 当请求中获取session时,先从调用findSession() 从内存sessions 中查找。
  2. 如果内存中找不到 则调用 swapIn() 方法,进行查找,判断该session是否钝化了,如果钝化则把该session活化加载到内存。

swapIn() 方法

Tomcat 之 Session的活化和钝化 源码分析_第13张图片

为当前查找的session设置一个lock。

Tomcat 之 Session的活化和钝化 源码分析_第14张图片
  1. 双重检查,在锁中再次判断sessions中是否有此session。
  2. 从store中加载session。
  3. 如果store 有此session 并判断该session是否过期,并做处理
Tomcat 之 Session的活化和钝化 源码分析_第15张图片
  1. 通过tellNew() 调用 web.xml 中注册HttpSessionListener的事件
  2. 把session添加到sessions 集合中。
  3. 通过activate()方法调用web.xml中注册的HttpSessionActivationListener事件
  4. 最后把该session相关的锁,删除。

想了解更多精彩内容请关注我的公众号

Tomcat 之 Session的活化和钝化 源码分析_第16张图片

你可能感兴趣的:(Tomcat 之 Session的活化和钝化 源码分析)