`
michael.softtech
  • 浏览: 208603 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

tomcat session管理

阅读更多

最近有空看了一下tomcat 6源码里面对session管理的实现,现在写下来,以供后考,也希望能对对此感兴趣的朋友

有所提示。

 

闲话少说,先贴一下tomcat6的component层次图(此图来自tomcat doc)

  Server                                         就是一个servlet container
           |
         Service                                 包含一个或多个connector的组        
           |
         Engine                                  servlet engine.最顶级的container.
           |  \
           |  --- Cluster --*
           |
         Host                                      第二级container
           |
         ------
        /      \
     Cluster    Context(1-N)             第三级container. servlet context. 也就是一个应用。
        |             \
        |             -- Manager               应用的session管理器
        |                   \
        |                   -- DeltaManager
        |                   -- BackupManager
        |
     ---------------------------
        |                       \
      Channel                    \
    ----------------------------- \
        |                          \
     Interceptor_1 ..               \
        |                            \
     Interceptor_N                    \
    -----------------------------      \
     |          |         |             \
   Receiver    Sender   Membership       \
                                         -- Valve
                                         |      \
                                         |       -- ReplicationValve
                                         |       -- JvmRouteBinderValve
                                         |
                                         -- LifecycleListener
                                         |
                                         -- ClusterListener
                                         |      \
                                         |       -- ClusterSessionListener
                                         |       -- JvmRouteSessionIDBinderListener
                                         |
                                         -- Deployer
                                                \
                                                 -- FarmWarDeployer
     

OK,基本层级关系说过了,就开始分析session的管理。

1. session 的创建。

   更正:下面这段我理解错了。其实进一步看下来,发现其实session的创建是在每个context里面。具体的创建可以看我

   这篇之后的那篇文章. Session的生成实际是在调用最终处理的servlet的时候生成的。

    session的创建的入口是在Host里面,每次request进来之后,会沿着container 的pipeline一直往下进行、

    处理,顺序是:engine->host->context->wrapper. 而pipeline的作用就是调用对应级别的value对

   request和response进行处理。在StandardHostValue里面首先出现对session的调用:

 

public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Select the Context to be used for this Request
        Context context = request.getContext();
        if (context == null) {
            response.sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 sm.getString("standardHost.noContext"));
            return;
        }

        // Bind the context CL to the current thread
        if( context.getLoader() != null ) {
            // Not started - it should check for availability first
            // This should eventually move to Engine, it's generic.
            Thread.currentThread().setContextClassLoader
                    (context.getLoader().getClassLoader());
        }

        // Ask this Context to process this request
        context.getPipeline().getFirst().invoke(request, response);

        // Access a session (if present) to update last accessed time, based on a
        // strict interpretation of the specification
        if (Globals.STRICT_SERVLET_COMPLIANCE) {
            request.getSession(false);
        }

        // Error page processing
        response.setSuspended(false);

        Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);

        if (t != null) {
            throwable(request, response, t);
        } else {
            status(request, response);
        }

        // Restore the context classloader
        Thread.currentThread().setContextClassLoader
            (StandardHostValve.class.getClassLoader());

    }

 

    注意里面的:request.getSession(false) 这一句。这一句最终会调用如下代码;

  

 protected Session doGetSession(boolean create) {

        // There cannot be a session if no context has been assigned yet
        if (context == null)
            return (null);

        // Return the current session if it exists and is valid
        if ((session != null) && !session.isValid())
            session = null;
        if (session != null)
            return (session);

        // Return the requested session if it exists and is valid
        Manager manager = null;
        if (context != null)
            manager = context.getManager();
        if (manager == null)
            return (null);      // Sessions are not supported
        if (requestedSessionId != null) {
            try {
                session = manager.findSession(requestedSessionId);
            } catch (IOException e) {
                session = null;
            }
            if ((session != null) && !session.isValid())
                session = null;
            if (session != null) {
                session.access();
                return (session);
            }
        }

        // Create a new session if requested and the response is not committed
        if (!create)
            return (null);
        if ((context != null) && (response != null) &&
            context.getCookies() &&
            response.getResponse().isCommitted()) {
            throw new IllegalStateException
              (sm.getString("coyoteRequest.sessionCreateCommitted"));
        }

        // Attempt to reuse session id if one was submitted in a cookie
        // Do not reuse the session id if it is from a URL, to prevent possible
        // phishing attacks
        if (connector.getEmptySessionPath() 
                && isRequestedSessionIdFromCookie()) {
            session = manager.createSession(getRequestedSessionId());
        } else {
            session = manager.createSession(null);
        }

        // Creating a new session cookie based on that session
        if ((session != null) && (getContext() != null)
               && getContext().getCookies()) {
            Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,
                                       session.getIdInternal());
            configureSessionCookie(cookie);
            response.addCookieInternal(cookie, context.getUseHttpOnly());
        }

        if (session != null) {
            session.access();
            return (session);
        } else {
            return (null);
        }

    }

   

  通过以上代码,container或者返回一个已存在的session,或者新建一个session,或者返回Null(特殊情况).

      而session的创建是由manager完成的。Manager接口的实现根据具体情况有很多种,比如:

      StandardManager:默认的单机环境tomcat session manager.创建standardsession.

      DeltaSessionManager:适用于集群环境。创建DeltaSession

      ....

     不同的Manager管理不同具体类型的session,从而使得tomcat能够很好的支持集群环境下面的session复制,持久化 等等。比如DeltaSession创建session的时候,会向集群中的其他节点群播一个信息。

   

 

2. session的管理。

    大家都知道tomcat的session需要不断使超时的session失效,那么这个共是怎么实现的呢?

    在StandardContext启动的时候哦,会同时启动一个thread. 这个线程是一个daemon线程,

   会定时调用ManagerBase的一下方法:

  

public void processExpires() {

        long timeNow = System.currentTimeMillis();
        Session sessions[] = findSessions();
        int expireHere = 0 ;
        
        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具体实现的。比如DeltaSession:

  

 public void expire(boolean notify, boolean notifyCluster) {
        if (expiring)
            return;
        String expiredId = getIdInternal();

        if(expiredId != null && manager != null &&
           manager instanceof DeltaManager) {
            DeltaManager dmanager = (DeltaManager)manager;
            CatalinaCluster cluster = dmanager.getCluster();
            ClusterMessage msg = dmanager.requestCompleted(expiredId, true);
            if (msg != null) {
                if(dmanager.doDomainReplication()) {
                    cluster.sendClusterDomain(msg);
                } else {
                    cluster.send(msg);
                }
            }
        }

        super.expire(notify);

        if (notifyCluster) {
            if (log.isDebugEnabled())
                log.debug(sm.getString("deltaSession.notifying",
                                       ((ClusterManager)manager).getName(), 
                                       new Boolean(isPrimarySession()), 
                                       expiredId));
            if ( manager instanceof DeltaManager ) {
                ( (DeltaManager) manager).sessionExpired(expiredId);
            }
        }
    }

 

    可以看出,当session失效的时候,manager会广播这个消息。

分享到:
评论

相关推荐

    tomcat-redis-session管理 使用说明

    【标题】:“Tomcat-Redis-Session管理”的实践指南 在Web应用开发中,Session管理是关键的一环,用于在用户浏览器与服务器之间保持状态。传统的Session存储方式是将数据存放在服务器内存中,但随着高并发访问和...

    tomcat-session同步所需jar.rar_session集群共享_tomcat session

    在IT行业中,尤其是在Java Web应用领域,Tomcat服务器的session管理是至关重要的。"tomcat-session同步所需jar.rar_session集群共享_tomcat session"这个标题表明我们关注的是如何在Tomcat集群环境中实现session的...

    tomcat-redis-session-manager包集合下载(tomcat8)

    综上所述,"tomcat-redis-session-manager包集合"为使用Tomcat8和JDK1.8的开发者提供了便捷的手段,通过集成Redis来增强session管理,提升应用在分布式环境下的性能和可靠性。正确配置和使用这个工具可以显著改善...

    tomcat-session-manager环境构建资源

    在压缩包的文件名“tomcat-memcached”中,我们可以推断这个资源是关于Tomcat集成memcached进行Session管理的。Memcached是一个轻量级的内存存储系统,能够快速地存储和检索数据,特别适合用来存储像Session这样的...

    redis+tomcat实现session的jar

    根据压缩包子文件的文件名称"tomcat-redis-session-manage-tomcat7",可以推断出这是一个针对Tomcat7的Redis session管理模块。这个模块可能包含以下组件: 1. **Redis连接器**:负责建立和管理Tomcat与Redis服务器...

    深入浅析TomCat Session管理分析

    【深入浅析TomCat Session管理分析】 Session在Java Web开发中扮演着至关重要的角色,它允许服务器跟踪用户的交互,存储用户的状态信息。Tomcat作为广泛使用的开源Servlet容器,其内部的Session管理机制对于理解Web...

    设定tomcat中session过期时间.txt

    在Web开发中,Session管理是确保用户状态跟踪的重要机制之一。Tomcat作为一款广泛使用的Java应用服务器及Servlet容器,提供了多种方式来设定Session的有效时长。这有助于开发者根据具体业务需求灵活调整Session的...

    memcached-session-manager 实现 tomcat session共享

    **memcached-session-manager** 是一个开源项目,它实现了基于 Memcached 的 Tomcat Session 管理器。Memcached 是一个高性能、分布式的内存对象缓存系统,常用于减轻数据库的负载。将 Session 存储在 Memcached 中...

    tomcat-redis-session-manager.zip

    - `tomcat-catalina-7.0.61.jar` 和 `tomcat-servlet-api-7.0.61.jar`:这两个是Tomcat的核心组件,提供了Servlet容器的基本功能,包括Session管理接口。 - `jedis-2.7.2.jar`:这是Java对Redis的客户端库,提供了...

    tomcat-redis-session-manager-master

    "tomcat-redis-session-manager-master" 是一个项目名称,表明这是一个与Tomcat(一个流行的Java应用服务器)和Redis(一个开源的内存数据结构存储系统)相关的session管理器的主分支。通常,这样的项目是用来实现将...

    tomcat session存到mencache

    在处理用户会话时,Tomcat默认使用基于内存的session管理,但这可能导致在高并发场景下session数据丢失或者性能瓶颈。为了解决这些问题,可以将Tomcat的session存储机制改为Memcache,这是一种高效、分布式的内存...

    浅谈Tomcat Session管理分析

    上文中在Tomcat的context.xml中配置了Session管理器RedisSessionManager,实现了通过redis来存储session的功能;Tomcat本身提供了多种Session管理器,如下类图: 1.Manager接口类 定义了用来管理session的基本...

    springsession管理多台tomcatsession

    SpringSession 是一个强大的框架,它扩展了 Spring Framework 的 Session 支持,允许开发者在分布式环境中管理用户会话。尤其在处理多台 Tomcat 服务器时,SpringSession 提供了一种优雅的方式来实现 session 共享,...

    tomcat8专用session管理包.rar

    标题中的“tomcat8专用session管理包.rar”指的是一个针对Tomcat 8的特定session管理解决方案,这个压缩包包含了在使用Nginx作为反向代理服务器,并与Redis结合实现负载均衡场景下,确保Tomcat应用间session数据共享...

    redis-tomcat-session-manager.

    综上所述,`redis-tomcat-session-manager`是一个优化Tomcat Session管理的实践,通过集成Redis来提供更高效、可扩展的会话存储解决方案。配置过程中,需注意JAR包的添加、配置文件的替换以及正确设置Redis连接参数...

    tomcat8 Redis Session共享

    **Tomcat Session管理** 在Tomcat中,Session是用来存储用户会话状态的,包括用户的登录信息、购物车等。默认情况下,Session信息存储在服务器的内存中,如果服务器集群或者重启,这些信息将丢失。为了实现Session的...

    tomcat redis session.rar

    综上所述,"Tomcat Redis Session"是一种在分布式环境中保证用户会话一致性的解决方案,通过集成Redis和Nginx,有效地解决了Web应用集群中的Session管理难题。在实际部署中,还需要考虑系统整体架构、性能优化和运维...

    Tomcat_Session的持久化

    Tomcat_Session 的持久...Tomcat 提供了 StandardManager 和 PersistentManager 两个实现类来管理 Session,其中 PersistentManager 能够把 Session 对象保存到 Session Store 中,提供了更为灵活的 Session 管理功能。

    Tomcat8(Tomcat9)+redis实现Session共享(支持Redis集群)

    Tomcat作为最常用的Java Servlet容器,其Session管理能力直接影响到应用的性能和可扩展性。本教程将详细介绍如何利用Tomcat 8或9以及Redis实现Session共享,支持Redis集群,以提高系统的可伸缩性和数据一致性。 ...

Global site tag (gtag.js) - Google Analytics