`
zql3315
  • 浏览: 23768 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

tomcat的session实现原理

 
阅读更多

服务器端实现原理

Session在服务器端具体是怎么实现的呢?我们使用session的时候一般都是这么使用的:

request.getSession()或者request.getSession(true)。

这个时候,服务器就检查是不是已经存在对应的Session对象,见HttpRequestBase类doGetSession(boolean create)方法:

if ((session != null) && !session.isValid()) session = null;
        if (session != null) return (session.getSession());

        // 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) {
                return (session.getSession());
            }
        }

 

requestSessionId从哪里来呢?这个肯定是通过Session实现机制的cookie或URL重写来设置的。见HttpProcessor类中的parseHeaders(SocketInputStream input):

for (int i = 0; i < cookies.length; i++) {
            if (cookies[i].getName().equals(Globals.SESSION_COOKIE_NAME)) {
                // Override anything requested in the URL
                if (!request.isRequestedSessionIdFromCookie()) {
                    // Accept only the first session id cookie
                    request.setRequestedSessionId(cookies[i].getValue());
                    request.setRequestedSessionCookie(true);
                    request.setRequestedSessionURL(false);

                }
            }
        }


或者HttpOrocessor类中的parseRequest(SocketInputStream input, OutputStream output)

// Parse any requested session ID out of the request URI
        int semicolon = uri.indexOf(match); // match 是";jsessionid="字符串
        if (semicolon >= 0) {
            String rest = uri.substring(semicolon + match.length());
            int semicolon2 = rest.indexOf(';');
            if (semicolon2 >= 0) {
                request.setRequestedSessionId(rest.substring(0, semicolon2));
                rest = rest.substring(semicolon2);
            } else {
                request.setRequestedSessionId(rest);
                rest = "";
            }
            request.setRequestedSessionURL(true);
            uri = uri.substring(0, semicolon) + rest;
            if (debug >= 1)
                log(" Requested URL session id is " + ((HttpServletRequest) request.getRequest()).getRequestedSessionId());
        } else {
            request.setRequestedSessionId(null);
            request.setRequestedSessionURL(false);
        }


里面的manager.findSession(requestSessionId)用于查找此会话ID对应的session对象。Tomcat实现
是通过一个HashMap实现,见ManagerBase.java的findSession(String id):

 if (id == null) return (null);
 synchronized (sessions) {
       Session session = (Session) sessions.get(id);
       return (session);
 }

 
Session本身也是实现为一个HashMap,因为Session设计为存放key-value键值对,Tomcat里面Session实现类是StandardSession,里面一个attributes属性:

 /**
 * The collection of user data attributes associated with this Session.
 */
 private HashMap attributes = new HashMap();

 
所 有会话信息的存取都是通过这个属性来实现的。Session会话信息不会一直在服务器端保存,超过一定的时间期限就会被删除,这个时间期限可以在 web.xml中进行设置,不设置的话会有一个默认值,在tomcat目录下conf/web.xml中找到 <session-config> 元素,Tomcat的默认值是60分钟。那么服务器端是怎么判断会话过期的呢?原理服务器会启动一个线程,一 直查询所有的Session对象,检查不活动的时间是否超过设定值,如果超过就将其删除。见StandardManager类,它实现了Runnable 接口,里面的run方法如下:

 /**
       * The background thread that checks for session timeouts and shutdown.
       */
       public void run() {
       
       // Loop until the termination semaphore is set
           while (!threadDone) {
               threadSleep();
               proces***pires();
           }
       
       }
       
       /**
       * Invalidate all sessions that have expired.
       */
       private void proces***pires() {
       
           long timeNow = System.currentTimeMillis();
           Session sessions[] = findSessions();
           
           for (int i = 0; i < sessions.length; i++) {
               StandardSession session = (StandardSession) sessions[i];
               if (!session.isValid())
               continue;
               int maxInactiveInterval = session.getMaxInactiveInterval();
               if (maxInactiveInterval < 0)
               continue;
               int timeIdle = // Truncate, do not round up
               (int) ((timeNow - session.getLastUsedTime()) / 1000L);
               if (timeIdle >= maxInactiveInterval) {
                   try {
                       expiredSessions++;
                       session.expire();
                   } catch (Throwable t) {
                       log(sm.getString("standardManager.expireException"), t);
                   }
               }
           }
       
       }

 
Session 信息在create,expire等事情的时候都会触发相应的Listener事件,从而可以对session信息进行监控,这些Listener只需要 继承HttpSessionListener,并配置在web.xml文件中。如下是一个监控在线会话数的Listerner:

public class MySessionListener implements HttpSessionListener {

    public void sessionCreated(HttpSessionEvent event) {

        HttpSession session = event.getSession();

        ServletContext application = session.getServletContext();

        // 在application范围由一个HashSet集保存所有的session

        HashSet sessions = (HashSet) application.getAttribute("sessions");

        if (sessions == null) {

            sessions = new HashSet();

            application.setAttribute("sessions", sessions);

        }

        // 新创建的session均添加到HashSet集中

        sessions.add(session);

        // 可以在别处从application范围中取出sessions集合

        // 然后使用sessions.size()获取当前活动的session数,即为“在线人数”

    }

    public void sessionDestroyed(HttpSessionEvent event) {

        HttpSession session = event.getSession();

        ServletContext application = session.getServletContext();

        HashSet sessions = (HashSet) application.getAttribute("sessions");

        // 销毁的session均从HashSet集中移除

        sessions.remove(session);

    }

}

 

 

分享到:
评论

相关推荐

    nginx实现多个tomcat7直接session共享所需jar包

    标题中的“nginx实现多个tomcat7直接...以上就是关于“nginx实现多个tomcat7直接session共享所需jar包”的详细解释,包括了Session共享的背景、原理以及可能的实现方法。希望这些信息能帮助你理解和解决实际问题。

    tomcat集群实现session复制

    在IT领域,特别是Web应用服务器的管理与优化中,Tomcat集群实现Session复制是一个关键的技术点,它确保了高可用性和负载均衡,特别是在处理大量并发请求的场景下。本文将深入探讨这一主题,涵盖其原理、配置方法以及...

    tomcat-redis-session-manager实现session共享 配置文件

    "tomcat-redis-session-manager"是一个解决方案,它将用户的Session信息存储在Redis缓存服务器中,从而实现跨服务器的Session共享。本篇文章将深入探讨这个话题,包括它的原理、配置以及实际应用。 **一、Session...

    Tomcat_Session的持久化

    下面详细讲解 Tomcat_Session 的持久化原理和实现机制。 一、Session 的使用 Session 是一种用来跟踪用户状态的机制。Servlet 容器通过在客户端浏览器中保存一个 Session ID 来跟踪 Session。调用 session.getID()...

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

    "tomcat-session同步所需jar.rar_session集群共享_tomcat session"这个标题表明我们关注的是如何在Tomcat集群环境中实现session的共享。这涉及到多个知识点,包括session的基本概念、session复制、粘滞会话、以及...

    memcached-session-manager 实现 tomcat session共享

    标题 "memcached-session-manager 实现 tomcat session共享" 指的是在分布式环境中,通过 memcached-session-manager 这个工具来实现 Tomcat 应用服务器之间的 Session 共享。Session 是 Web 应用中用于存储用户状态...

    集群redis实现session共享jar包之tomcat8

    本篇文章将深入探讨在Tomcat 8中通过`集群redis`实现session共享的方法。 一、session共享的重要性 在Web应用中,session是服务器端用来存储用户状态的一种机制,比如用户的登录信息、购物车内容等。在单台服务器...

    Tomcat中实现Session小结

    在本文中,我们将深入探讨Tomcat服务器中实现Session的相关知识,这包括Session的基本概念、目的、实现机制以及通过示例进行的详细解析。 **什么是Session?** Session是Web开发中用来跟踪用户状态的一种机制。...

    tomcat-redis-session

    使用tomcat-redis-session-manager开源框架实现使用Redis存储Nginx+Tomcat负载均衡集群的Session所需要的3个jar:tomcat-redis-session-1.0-SNAPSHOT.jar、jedis-2.7.2.jar、commons-pool2-2.0.jar

    tomcat服务器工作原理

    Tomcat支持集群部署,通过复制Session数据和负载均衡,实现高可用性和水平扩展。 理解Tomcat的工作原理有助于我们更好地管理和优化Java Web应用,提升服务器性能,解决运行中可能出现的问题。通过深入学习,我们...

    Memcached+tomcat session共享jar 和tomcat xml配置

    本篇将深入探讨如何使用Memcached实现Tomcat的Session共享,并基于提供的jar文件和Tomcat的XML配置进行详细讲解。 首先,我们需要理解Memcached的工作原理。Memcached是一个基于内存的键值对存储系统,用于临时存储...

    tomcat集群session共享jar tomcat7专用jar

    2. `tomcat-redis-session-manager.jar`:这个是Tomcat的Redis Session Manager实现,它负责在Tomcat容器内部将Session数据保存到Redis中。 安装步骤如下: 1. 下载并添加上述jar包到Tomcat的`lib`目录,确保...

    tomcat session共享负载

    本文将深入探讨如何在Tomcat中实现Session的共享,并分析其背后的原理和配置方法。 首先,我们要理解Session的基本概念。Session是Web服务器为用户创建的一段持久性存储空间,用于存储用户在访问网站期间产生的状态...

    tomcat session redis支持

    Tomcat可以通过使用一个名为`Tomcat-Redis Session Manager`的插件来实现这一功能。这个插件允许Tomcat将session序列化并存储在Redis中,然后在需要时反序列化回session对象。 实现步骤如下: 1. **安装Redis**:...

    tomcat集群session共享解决方案

    在分布式系统中,Tomcat集群是一种常见的架构模式,用于提高应用程序的可用性和可扩展性。...同时,理解负载均衡原理、分布式系统设计以及安全性问题也是至关重要的,这将有助于你构建更健壮、高效的Tomcat集群。

    tomcat-redis-session管理 使用说明

    通过将Tomcat的Session数据序列化后存入Redis,可以实现跨服务器的Session共享,提高可扩展性和高可用性。 【三、集成Tomcat与Redis】 1. 添加依赖:首先,需要将Redis客户端的JAR包(如jedis)引入到Tomcat的lib...

    tomcat的内部原理

    Tomcat是Apache软件基金会的Java Servlet容器,它实现了Java EE中的Web应用服务器规范。深入理解Tomcat的内部原理有助于我们更好地管理和优化Web应用程序的性能。以下是对Tomcat主要组成部分的详细解析: 1. Server...

    集群redis实现session共享jar包之tomcat7

    下面将详细解释这一技术的实现原理和步骤。 首先,理解Session共享的必要性。当多个服务器实例共同处理一个用户会话时,每个服务器都需要访问相同的数据,否则会导致会话状态丢失。传统的基于Cookie的解决方案不能...

    tomcat 工作原理

    《Tomcat工作原理详解》 Tomcat作为一款广泛使用的开源Java应用服务器,其工作原理是许多开发者想要深入了解的关键。本文将从多个层面深入探讨Tomcat的运作机制,旨在帮助读者全面理解其设计思想和核心功能。 一、...

Global site tag (gtag.js) - Google Analytics