前言

偶然发现Tomcat会话时间的半小时,并不是说“会话创建后只有半小时的有效使用时间”,而是说“会话空闲半小时后会被删除”。索性就翻了一下源码。做了一番整理。

注:空闲时间,指的是同一个会话两次请求之间的间隔时间

Session相关类图

  • HttpSession就是大家Servlet层可以直接使用的Session.
  • Session是Tomcat内部使用的接口,可以做一些内部调用
  • StandardSession是标准的HttpSession实现,同时它也实现了Session接口,用于Tomcat内部管理
  • StandardSessionFacade,类名已经指明它就是一个“门面类”,它内部会引用一个StandardSession的对象,但对外只提供HttpSession规定的方法。

Manager相关类图

StandardManager与PersitentManager都是Manager的实现,但是它们在存储Session对象的方式上有所不同。

StandarManager

1.Tomcat运行时,把Session存储在内存中

2.Tomcat关闭时(注意是正常的关闭操作,如执行stop.sh,而非突然崩溃),会把Session写入到磁盘中,等到Tomcat重启后再把Session加载进来

PersistentManager

1.总是把Session存储在磁盘中。

Manager与Context的关系

在Tomcat中,一个Context就是部署到Tomcat中的一个应用(Webapp)。每一个Context都有一个单独的Manager对象来管理这个应用的会话信息。

Manager如何存储Session

Manager对象会使用一个Map来存储Session对象

  • Key  => SessionId
  • Value  => Session Object
    /**
* The set of currently active Sessions for this Manager, keyed by
* session identifier.
*/
protected Map<String, Session> sessions = new ConcurrentHashMap<>();

当一个请求到达Context的时候,如果它带有JSESSIONID的Cookie,Manager就能依此找到关联的Session对象,放入到Request对象中。

Manager的定期检查

Manager接口有一个backgroundProcess()方法,顾名思义就是后台处理。

    /**
* This method will be invoked by the context/container on a periodic
* basis and allows the manager to implement
* a method that executes periodic tasks, such as expiring sessions etc.
*/
public void backgroundProcess();

注:Container接口也有这个方法,这个方法一般在容器启动(start)的时候,开启一个额外的线程来循环执行这个backgroundProcess方法。Context的这个方法启动后,会执行Loader和Manager的backgroundProcess方法。

我们来看看这个方法都做了些什么?

/**
* {@inheritDoc}
* <p>
* Direct call to {@link #processExpires()}
*/
@Override
public void backgroundProcess() {
count = (count + 1) % processExpiresFrequency;
if (count == 0) //如果达到检查频率则开始检查
processExpires();
} /**
* Invalidate all sessions that have expired.
*/
public void processExpires() { long timeNow = System.currentTimeMillis();
Session sessions[] = findSessions(); //获取所有session对象
int expireHere = 0 ; //过期session的数量,不要被这个变量名骗了 if(log.isDebugEnabled())
log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
if (sessions[i]!=null && !sessions[i].isValid()) {
expireHere++;
}
}
long timeEnd = System.currentTimeMillis();
if(log.isDebugEnabled()) //打印记录
log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow ); }

很多人看到这里,可能会有跟我一样的疑惑,即这里面根本就没有使Session过期失效的操作,好像只做了状态检查。不过后来看到了Session的isValid方法的实现就都明白了。

/**
* Return the <code>isValid</code> flag for this session.
*/
@Override
public boolean isValid() { if (!this.isValid) {
return false;
} if (this.expiring) {
return true;
} if (ACTIVITY_CHECK && accessCount.get() > 0) {
return true;
} //关键所在
//如果有设置最大空闲时间
//就获取此Session的空闲时间进行判断
//如果已超时,则执行expire操作
if (maxInactiveInterval > 0) {
int timeIdle = (int) (getIdleTimeInternal() / 1000L);
if (timeIdle >= maxInactiveInterval) {
expire(true);
}
} return this.isValid;
}

 那这个空闲时间怎么得到?

其实就是记录上一次请求的时间,然后与本次请求的时间进行比对,得到时间差。

总结

总的来说,就是用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁。

【详解】Tomcat是如何监控并删除超时Session的?的更多相关文章

  1. 详解Tomcat 配置文件server.xml

    前言 Tomcat隶属于Apache基金会,是开源的轻量级Web应用服务器,使用非常广泛.server.xml是Tomcat中最重要的配置文件,server.xml的每一个元素都对应了Tomcat中的 ...

  2. 详解tomcat的连接数与线程池

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  3. 详解Tomcat的连接数和线程池

    转: https://www.cnblogs.com/kismetv/p/7806063.html#t11 前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须 ...

  4. 详解 Tomcat 的连接数与线程池

      前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server. ...

  5. 详解tomcat连接数和线程数

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). 在前面的文章 详解Tomcat配置文件server.xm ...

  6. 【转】详解tomcat的连接数与线程池

    对tomcat线程池.Connector的BIO.NIO解析的很透彻的一篇文章. 原文链接:https://www.cnblogs.com/kismetv/p/7806063.html 前言 在使用t ...

  7. 【tomcat系列】详解tomcat架构(上篇)

    java中,常用的web服务器一般由tomcat,weblogic,jetty,undertwo等,但从用户使用广泛度来说,tomcat用户量相对比较大一些,当然这也基于它开源和免费的特点. 从软件架 ...

  8. 详解Tomcat核心配置、http协议

    Tomcat服务器 Tomcat配置与部署(IDEA) https://www.cnblogs.com/gonghr/p/14731266.html Tomcat手工创建和打包第一个Web工程 在ap ...

  9. 详解 Spotlight on MySQL监控MySQL服务器

    前一章详解了Spotlight on Unix 监控Linux服务器 ,今天再来看看Spotlight on MySQL怎么监控MySQL服务器. 注:http://www.cnblogs.com/J ...

随机推荐

  1. 突破内网限制上网(ssh+polipo)

    最近到客户这里来做项目,发现客户对网络的把控实在严格,很多网站都不能访问到,搜索到的技术文档也屏蔽了.突然想到了FQ工具的原理,刚好自己也有台服务器在外头,部署个Polipo代理然后用ssh隧道连接. ...

  2. MySQL数据库(二)-数据库的增删改查

    简介: 以下是MySQL最基本的增删改查语句.在进行“增删改查”的操作之前,先建立一个包含数据表student的数据库,新建表grade(具体操作可以见上一篇). 一."增"-添加数据 1.1 为表中 ...

  3. 自定义react-navigation的TabBar

    在某些情况下,默认的react-navigation的tab bar无法满足开发者的要求.这个时候就需要自定义一个tab bar了.本文就基于react-navigtion v2来演示如何实现一个自定 ...

  4. SSM_CRUD新手练习(10)返回分页的JSON数据

    我们完成了员工的分页查询,但是现在这种做法只能适应浏览器和服务器的交互模式,但在移动互联网时代,客户端不仅仅只有浏览器,还有安卓和IOS客户端.我们的解决方式是AJAX+JSON方式来实现平台无关性. ...

  5. .NET默认一个客户端对同一个服务器地址同时只能建立2个TCP连接

    做一个客户端的测试小程序测试web service的并发处理.开始用async task做,不管创建多少个task,用netstat看同时只有两个tcp连接.以为是async task的问题,改用Ba ...

  6. Appium日志乱码终结指北

    缘起 最近Android,IOS自动化多开群控都搞好了,但是Appium中的log 显示中文乱码问题像个苍蝇一样,看着感觉特别难受,挥之不去,抚之不平.论坛搜索了一下,很多帖子都反映过这个问题,但是都 ...

  7. Android中RecyclerView出现java.lang.IndexOutOfBoundsException

    在RecyclerView更细数据时出现java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder ...

  8. 读书笔记二 How Does the Internet work?

    原文链接:  https://web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm 先写写 ...

  9. Tmux会话的使用

    不想看废话的直接拖到下面看干货部分! 我们管理Linux服务器通常是通过ssh远程连接过去,如果在服务器上执行比较耗时的操作,比如下载安装软件.编译等等,如果需要数个小时来完成这些工作,但是又不得不关 ...

  10. text-decoration:[ text-decoration-line ] || [ text-decoration-style ] || [ text-decoration-color ] 默认值:

    css3中字体装饰,多样化的界面效果,: [ text-decoration-line ]:指定文本装饰的种类.相当于CSS2.1的 text-decoration 属性, 可取值:none | un ...