`
cectsky
  • 浏览: 46950 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

HttpSession 失效的内部机制

 
阅读更多

周六在公司加班,研究了下tomcat session失效的原理,直接上code,以后再补齐一些基本concept.

 

starttime = 2012-11-24 2:57pm (好久没update blog 看看写一篇用多久)

 

2种方式注销session

 

(1)主动 invoke Servlet API 

 

/**
     * Invalidates this session then unbinds any objects bound to it.
     * 
     * @exception IllegalStateException
     *                if this method is called on an already invalidated session
     */
public void invalidate();

 

 

说明:这是HttpSession规范中定义的interface, 看note说将一个session注销然后解除其他对象的绑定. 也就是删除掉session object. 它要求throw 一个Exception

 

tomcat中实现是先 check session object 是不是valid的,如果invalid 直接throw IllegalStateException

然后开始处理,如下

 

    /**
     * Perform the internal processing required to invalidate this session,
     * without triggering an exception if the session has already expired.
     *
     * @param notify Should we notify listeners about the demise of
     *  this session?
     */
    public void expire(boolean notify) {

        // Check to see if expire is in progress or has previously been called
        if (expiring || !isValid)
            return;

        synchronized (this) {
            // Check again, now we are inside the sync so this code only runs once
            // Double check locking - expiring and isValid need to be volatile
            if (expiring || !isValid)
                return;

            expiring = true;
            setValid(false);
            manager.remove(this, true);//在管理对象中讲这个session object删除(内部也是map实现的)

            // 此处nofity标示是否在注销session的时候发送Evnet给listener,典型的观察者pattern
            if (notify) {
                fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null);
            }

            expiring = false;

            // Unbind any objects associated with this session
            String keys[] = keys();
            for (int i = 0; i < keys.length; i++)
                removeAttributeInternal(keys[i], notify);

        }

    }

 

 

Note that:这段代码就是对specification的标准实现 我精简了一些,从code中学习到了一些知识

(1)如何扩展specification

(2)多线程争用,这个invalid其实是存在多线程mutex操作的。如果一个Thread_A将标志修改了,Thread_B一定要及时知道,所以对操作加以synchronized,对信号量如expiring variable采取volatile修饰保证内存可见性

(3)对于notification, 运用经典的观察者pattern

(4)其实tomcat的session实现还用到了外观等其他design pattern.(面试必背设计模式啊,哈哈)

(5)Map的组合应用(这个地球人都知道,我就不说了)

 

(2) timeout 注销

这个timeout最近深有体会,因为项目设计多线程并发,所以不确定因素很多,比如测试ftp connection等,也不能一直让它retrieve啊,哈哈,相信大家比我理解的深刻。

 

web app中大家都会配置timeout, 比如写在code中 或者xml中的session-timeout node里面,下面share下我学习的内部实现

 

容器类ContainerBase开始启动(tomcat定义了一套组件的lifecycle管理的,还没学习完),然后初始化init方法中开始做一些准备,最后会start一个thread来进行timeout check 的工作(this thread is a daemon thread)

具体的逻辑处理看code

 

    /**
     * Execute a periodic task, such as reloading, etc. This method will be
     * invoked inside the classloading context of this container. Unexpected
     * throwables will be caught and logged.
     */
    @Override
    public void backgroundProcess() {
        if (!getState().isAvailable())
            return;

        if (cluster != null) {...}
        if (loader != null)  {...}          
        if (manager != null) {
            manager.backgroundProcess();              
        }
       //下面做一些pipe的信息处理和事件动作,不是重点就不说了
    }

 

 

manager是session的管理对象,此处会调用它的处理逻辑,code如下

 

    /**
     * 此处比较有创意,是说这个Container被框架每调用6次,就会check一次session timeout 6次是默认的数值
     */
    @Override
    public void backgroundProcess() {
        count = (count + 1) % processExpiresFrequency;
        if (count == 0)
            processExpires();
    }

 核心check timeout的逻辑就很简单了,上次access的时间和这次access的时间间隔是否大于我们定义的timeout.

 

学习到的东东:

(1)lifecycle

(2)线程执行方式

(3)模块化分类,code编码等等

 

nowtime=2012-11-24 3:28pm

cost = nowtime - starttime = 31min

 

用了30多分钟,失败,下篇一定要控制在30min-

 

有说的不对的地方请指教, 本文绝对原创,如需转载,注明出处(估计没人看)

分享到:
评论

相关推荐

    Session机制总结

    - **设置Session值**:在服务器端,通过`HttpSession`接口的`setAttribute()`方法可以设置Session的键值对,例如`session.setAttribute("username", "张三")`。 - **获取Session值**:使用`getAttribute()`方法可以...

    SpringMVC拦截器实现监听session是否过期详解

    在这个方法内部,首先获取到请求对应的session对象,然后从application(即ServletContext)中通过session的ID来检索是否已存在该session对象。如果不存在,表示用户没有登录或者session已经过期,此时拦截器会拦截...

    session.会话实例源码

    源码分析可以让我们了解Session是如何在内部管理这些操作的,包括Session ID的生成、数据的序列化与反序列化,以及超时机制。 **5. 实例:使用Session进行状态管理** 以下是一个简单的Java Servlet示例,展示了如何...

    Session

    Session的主要优点在于它可以跨多个页面保持用户状态,但缺点是如果会话过多,服务器内存压力会增大,且如果用户禁用Cookie,Session管理可能会失效。 描述中提到的链接指向了一个博客文章,虽然具体内容未给出,但...

    servlet源码包

    4. **会话管理**:研究`HttpSession`接口,理解如何存储和检索会话数据,以及会话超时和失效的机制。 5. **JSP转换过程**:了解JSP文件是如何被编译成Servlet Java源码,再编译为字节码并加载到内存中执行的。 6. **...

    SERVLET代码

    6. **转发与重定向**:在Servlet中,可以使用`RequestDispatcher`的`forward()`方法进行请求转发,这会在服务器内部将请求传递给另一个资源;而`sendRedirect()`方法则是客户端重定向,浏览器会发起一个新的请求。 ...

    cookie

    标签“源码”意味着该文章可能包含了对Cookie机制的源代码解析,帮助读者理解其内部工作流程。而“工具”可能指的是与Cookie管理相关的开发者工具或者辅助库,如浏览器的开发者工具或者某种编程框架提供的Cookie操作...

    Servlet API

    监听器是实现特定事件监听的接口,如`ServletContextListener`监听应用上下文的初始化和销毁,`HttpSessionListener`监听会话的创建和失效。它们可以在关键事件发生时执行自定义逻辑。 9. **MVC框架与Servlet** ...

    javaweb学习资料

    验证码是一种防止自动机器人或恶意用户进行非法操作的安全机制。在JavaWeb中,我们可以使用图像验证码,通过生成随机字符串并将其显示在图像上,然后让用户输入看到的字符串。这通常涉及到图像处理(如使用`java....

Global site tag (gtag.js) - Google Analytics