Tomcat中session的管理机制

 更新时间:2016年09月24日 10:07:43   作者:锐洋智能  
这篇文章主要为大家详细介绍了Tomcat中session的管理机制 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

详细描述Tomcat中session的管理机制:

1. 请求过程中的session操作:

简述:在请求过程中首先要解析请求中的sessionId信息,然后将sessionId存储到request的参数列表中。然后再从 request获取session的时候,如果存在sessionId那么就根据Id从session池中获取session,如果sessionId不 存在或者session失效,那么则新建session并且将session信息放入session池,供下次使用。

(1)SessionId解析过程时序图:


概述:首先用户发送一个http请求传递给Http11Processor,经由Http11Processor解析封装在org.apache.coyote.Request然后传递给CoyoteAdapter,coyoteAdapter是一个适配器,将coyote框架封装的org.apache.coyote.Request适配给org.apache.catalina.connector.Request(这个流程不多说,之前都有总结过),转换完之后会调用parsePathParameters方法去解析路径参数中的cookie信息(因为当cookie被浏览器禁用时,会将cookie信息重写进url),先尝试从url中尝试解析出sessionId. 然后会调用parseSessionCookiesId,这个就是从cookie中解析sessionId存到request(parsePathParameters和parseSessionCookiesId方法,在调用过程中,没有看到明显的异或逻辑,即两者都执行了,但这样不是就有问题了吗?想想其实没有问题的,URL重写设置sessionId或者放到cookie中传递过来,两者方式只会用一个,想到这点就知道没有问题了)解析到sessionId就放到了request里面。解析SessionId的逻辑就ok了。

下面贴出关键代码:

ParsePathParameters方法(从重写URL中解析):


Ps: 标记出来的部分分别是从URL解析出变量,然后放到request参数列表里面。

parseSessionCookiesId方法(从cookie中解析出sessionId):


Ps: 上面的标记就是从cookie中获取sessionId.看第一个标记有个SessionConfig.getSessionCookieName(context)的调用,这里会获取到一个默认的sessionId的key,这个key是定义在SessionConfig中的,其值为jsessionId:

(2) 从请求中获取session的流程基本就是上文描述的这样。那么再看一下Servlet获取session的流程:

概述:appServlet是我们自己定义的一个Servlet,在通过Reqest获取session的时候,其实调用的这个HttpServletRequest(是一个接口)其实是RequestFacade(封装了org.apache.catalina.connector.Request的一个门面),然后RequestFacade会调用真实的Request的getSession方法。Request具体的逻辑是调用Context容器的getManger方法获取Session管理器(session管理器详情下文介绍),然后如果SessionId如果已经被解析出来了,那么则会调用findSession方法从session对象池中获取对应的session,反之如果sessionId不存在,则需要重新创建一个Session,并放入session对象池中。

下面贴出关键代码:

类RequestFacade的getSession方法:


类Request的getSession方法:


类Request的doGetSession方法:



Ps:第一个标记就是根据SessionId从session对象池中获取session信息,第二标记就是在没有解析到sessionId的情况下创建一个新的Session对象。

这个创建一个新的session这里点涉及到新的sessionId的生成,生成sessionId的逻辑关键代码是在类SessionIdGenerator中的generateSessionId方法中定义:

以上即是Servlet获取session的流程,下文具体总结一下tomcat是怎么来管理Session的,即session管理器的知识。

2. Session的管理机制

Session管理器定义:Session管理器组件负责管理Session对象,例如,创建和销毁Session对象。

首先看一张Session管理器的类继承结构图(这个是tocmat7.x的图,tomcat5的类继承机构和这个有很大不同):


简述:下面依次总结下每个类(参考官网信息):

(1)Manager:定义了关联到某一个容器的用来管理session池的基本接口。

(2)ManagerBase:实现了Manager接口,该类提供了Session管理器的常见功能的实现。

(3)StandardManager:继承自ManagerBase,tomcat的默认Session管理器(不指定配置,默认使用这个),是tomcat处理session的非集群实现(也就说是单机版的),tomcat关闭时,内存session信息会持久化到磁盘保存为SESSION.ser,再次启动时恢复。

(4)PersistentManagerBase:继承自ManagerBase,实现了和定义了session管理器持久化的基础功能。

(5)PersistentManager:继承自PersistentManagerBase,主要实现的功能是会把空闲的会话对象(通过设定超时时间)交换到磁盘上。

(6)ClusterManager:实现了Manager接口,通过类名应该能猜到,这个就是管理集群session的管理器和上面那个StandardManager单机版的session管理器是相对的概念。这个类定义类集群间session的复制共享接口。

(7)ClusterManagerBase:实现了ClusterManager接口,继承自ManagerBase。该类实现了session复制的基本操作。

(8)BackupManager:继承自ClusterManagerBase, 集群间session复制策略的一种实现,会话数据只有一个备份节点,这个备份节点的位置集群中所有节点都可见。这种设计使它有个优势就是支持异构部署。

(9)DeltaManager:继承自ClusterManagerBase,集群建session复制策略的一种实现,和BackupManager不同的是,会话数据会复制到集群中所有的成员节点,这也就要求集群中所有节点必须同构,必须部署相同的应用。

补充:下面再具体总结一点就是在PersistentManagerBase类中有个成员变量Store:


持久化session管理器的存储策略就是有这个Store对象定义的,这个Store的类继承结构如下:


简述:接口Store及其实例是为session管理器提供了一套存储策略,store定义了基本的接口,而StoreBase提供了基本的实现。其中FileStore类实现的策略是将session存储在以setDirectory()指定目录并以.session结尾的文件中的。JDBCStore类是将Session通过JDBC存入数据库中,因此需要使用JDBCStore,需要分别调用setDriverName()方法和setConnectionURL()方法来设置驱动程序名称和连接URL。

3. Tomcat session相关的配置

从两个层面总结一下session相关的配置和设置。首先是从配置文件层面,session是有过期时间的,这个默认的过期时间是在$catalina_home/conf/web.xml有定义的。具体的默认配置如下(默认的过期时间是30min,即30min没有访问,session就过期了):


还有一点就是session管理如果不配置就默认使用StandardManager,但如果要配置的话可以在$catalina_home/conf/context.xml当中指定(其中从这个配置当中可以看到session管理器是和context容器关联的,也就说每个web应用都会有一个session管理器)具体的配置如下:


Tomcat7.x默认这个manager的配置是注释掉的。如果要指定的PersistentManager为默认管理器的话可以这么指定:


其实看到这也就发现了,其实session管理器或者Store存储策略,只要实现了相关的接口,都是可以自定义的。自己写一个配置在这里就ok了。

另外在从代码层面总结一下:session的一些配置信息是写死在代码里的,比如SessionConfig这个类就定义了一些session的设置信息。Session在cookie中的名字是JSESSION. Session通过URL重写的方式放在path里时,键值的名字是jsessionids,具体的代码如下:


还有一点就是sessionId默认指定的长度是16个字节,这个在SessionIdGenerator当中指定:


好了,有关默认配置的就先总结这么多。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot 如何将 Word 转换为 PDF

    Spring Boot 如何将 Word 转换为 PDF

    这篇文章主要介绍了Spring Boot将Word转换为 PDF,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • 浅谈Java基础知识之BigDecimal

    浅谈Java基础知识之BigDecimal

    我们又来回顾Java基础知识啦,今天讲的是BigDecimal的基本使用以及异常处理,下文中有非常详细的代码示例以及注释哦,需要的朋友可以参考下
    2021-05-05
  • 关于PreparedStatement的setObject作用及说明

    关于PreparedStatement的setObject作用及说明

    这篇文章主要介绍了关于PreparedStatement的setObject作用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • springboot打war包部署到外置tomcat容器的方法

    springboot打war包部署到外置tomcat容器的方法

    这篇文章主要介绍了springboot]打war包部署到外置tomcat容器,在这需要注意的是在boot-launch.war在tomcat webapps目录里面解压到boot-launch文件夹,感兴趣的朋友跟随小编一起看看吧
    2022-04-04
  • SpringBoot开发案例之打造私有云网盘的实现

    SpringBoot开发案例之打造私有云网盘的实现

    这篇文章主要介绍了SpringBoot开发案例之打造私有云网盘的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java中基于Nacos实现Sentinel规则持久化详解

    Java中基于Nacos实现Sentinel规则持久化详解

    这篇文章主要介绍了Java中基于Nacos实现Sentinel规则持久化详解,Sentinel Dashboard中添加的规则数据存储在内存,微服务停掉规则数据就消失,在⽣产环境下不合适,我们可以将Sentinel规则数据持久化到Nacos配置中⼼,让微服务从Nacos获取规则数据,需要的朋友可以参考下
    2023-09-09
  • MybatisPlus如何处理Mysql的json类型

    MybatisPlus如何处理Mysql的json类型

    这篇文章主要介绍了MybatisPlus如何处理Mysql的json类型,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • springboot整合shiro之thymeleaf使用shiro标签的方法

    springboot整合shiro之thymeleaf使用shiro标签的方法

    Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP ,这篇文章主要介绍了springboot整合shiro之thymeleaf使用shiro标签的相关知识,需要的朋友可以参考下
    2021-10-10
  • Java Map接口及其实现类原理解析

    Java Map接口及其实现类原理解析

    这篇文章主要介绍了Java Map接口及其实现类原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java程序单实例运行的简单实现

    Java程序单实例运行的简单实现

    这篇文章主要介绍了Java程序单实例运行的简单实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08

最新评论