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当中指定:

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

Tomcat中session的管理机制的更多相关文章

  1. tomcat中session在两个webapp中实现共享

    现在遇到一个需求就是要求完成简单的单点登录,通过在一个tomcat实例中放置两个webapps应用ROOT应用和CEO应用来完成在ROOT应用登录后,在CEO可以直接使用,而未在ROOT应用登录时,不 ...

  2. Nginx+Tomcat关于Session的管理

    前言 Nginx+Tomcat对Session的管理一直有了解,但是一直没有实际操作一遍,本文从最简单的安装启动开始,通过实例的方式循序渐进的介绍了几种管理session的方式. nginx安装配置 ...

  3. php中session的生成机制、回收机制和存储机制探究

    1.php中session的生成机制 我们先来分析一下PHP中是怎么生成一个session的.设计出session的目的是保持每一个用户的各种状态来弥补HTTP协议的不足(无状态).我们现在有一个疑问 ...

  4. Android中的内存管理机制以及正确的使用方式

    概述 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面来理解操 ...

  5. tomcat之Session的管理

    Session是由服务器端的应用服务器容器(如Tomcat.Jetty)存储的.下面分析一下Tomcat是如何管理Session的. 转自:tomcat架构分析 (Session管理) Tomcat中 ...

  6. php中session的运行机制

    在PHP中session默认是以文件的形式存储于服务器的 而客户端和服务端则是通过session_id来完成握手的,默认情况下PHP会将session_id存储于cookie中,用户每次请求时该ses ...

  7. tomcat中Servlet的工作机制

    在研究Servlet在tomcat中的工作机制前必须先看看Servlet规范的一些重要的相关规定,规范提供了一个Servlet接口,接口中包含的重要方法是init.service.destroy等方法 ...

  8. Tomcat中session共享问题的简单解决办法

    tomcat-redis-session-manager 使用redis配置tomcat共享session 结构图: 分析: 分布式web server集群部署后需要实现session共享,针对 to ...

  9. cocos2dx中的内存管理机制及引用计数

    1.内存管理的两大策略: 谁申请,谁释放原则(类似于,谁污染了内存,最后由谁来清理内存)--------->适用于过程性函数 引用计数原则(创建时,引用数为1,每引用一次,计数加1,调用结束时, ...

随机推荐

  1. GET和POST两种基本请求方法的区别(转载)

    get与post请求的区别: 通常回答: GET在浏览器回退时是无害的,而POST会再次提交请求. GET产生的URL地址可以被Bookmark,而POST不可以. GET请求会被浏览器主动cache ...

  2. 【LOJ】#2117. 「HNOI2015」实验比较

    题解 把所有=的点连起来,一个图合法肯定它是一个有向树森林 我们新建一个点,把这个点和其他所有树的树根连起来 定义\(dp[u][j]\)表示第u个点长度为j的序列的方案数 转移方法是 \(dp[u] ...

  3. spark优化之并行度

    这个其实我前面已经记录过了,这里在记录一下. 我可以通过参数人为的来控制分区大小,增加分区中即可增加任务的并行度,并行度高自然运行的就快了嘛. 官方推荐集群中每个cpu并行的任务是2-3个(也就是2- ...

  4. 029 RDD Join相关API,以及程序

    1.数据集 A表数据: 1 a 2 b 3 c B表数据: 1 aa1 1 aa2 2 bb1 2 bb2 2 bb3 4 dd1 2.join的分类 inner join left outer jo ...

  5. 002.Rsync详细配置项

    一 相关参数 全局参数 在文件中[module]之前的所有参数都是全局参数,当然也可以在全局参数部分定义模块参数,这时候该参数的值就是所有模块的默认值. port 指定后台程序使用的端口号,默认为87 ...

  6. 数据转换bug花了半天时间 Java.math.BigDecimal cannot be cast to java.lang.String

    从数据库取出一个 Count函数 统计的值 在代码中要转成Integer类型的时候 Integer.parseInt((String)map.get("ID_")) 报了一下错误: ...

  7. BZOJ3500 : PA2008 Cliquers

    设g[i]表示n=i时的答案,则OEIS上可以找到如下递推式: g[i]=g[i-1]+g[i-2]-g[i-5]-g[i-7]+... 其中符号为++--交替,第i项为f[i],f[1]=1,f[2 ...

  8. JVM启动流程

    JVM启动流程 (1)在java中jvm是通过java或javaw命令启动的,后面跟加载的类名. (2)jvm在启动的时候先根据[当前路径和系统版本寻找jvm的配置文件jvm.cfg]装载配置. (3 ...

  9. vue项目开发之v-for列表渲染的坑

    不知道大家在用vue开发的过程中有没有遇到过在使用v-for的时候会出现大片的黄色警告,比如下图: 其实这是因为没有写key的原因 :key是为vue的响应式渲染提供方法,在列表中单条数据改变的情况下 ...

  10. Upsync:微博开源基于Nginx容器动态流量管理方案

    Upsync:微博开源基于Nginx容器动态流量管理方案 https://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=404151075& ...