`
yjhexy
  • 浏览: 332279 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

tomcat session——对session的支持

阅读更多

一,tomcat 如何支持session

首先来看下$catalina.home/conf/context.xml

<Context>
    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
	
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    	-->
   <Manager className="org.apache.catalina.session.PersistentManager" checkInterval="1" maxIdleBackup="2"> 
		<Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" 
			connectionURL="jdbc:mysql://localhost:3306/session?user=root&amp;password=hello" 
			sessionTable="session" sessionIdCol="session_id" sessionDataCol="session_data" 
			sessionValidCol="sessionValid" sessionMaxInactiveCol="maxInactive" 
			sessionLastAccessedCol="lastAccess" sessionAppCol="appName" checkInterval="1" debug="99" />
	</Manager>

</Context>

 

众所周知 HTTP协议是说HTTP是无状态的,而我们常常使得程序有状态无非一种办法,把相同会话(即一组应当有状态的请求)都赋予一个统一的标识即JSESSIONID。

如果每次请求过来都带有JSESSIONID的话,那么这些请求都可以看成是同一个会话下的,那么会话中的状态就可以再服务端内存或者任何地方进行保存和关联。

 

1,那么这个JSESSIONID,首先是服务端生成的一个唯一标示(TOMCAT内部实现会帮我们自动生成)

2,其次这个JSESSIONID会被传给客户端。传给客户端有两种方式:

A,写到客户端Cookie里去。B,给客户端进行URL 的rewriter。

 

所以客户端拿到这个JSESSIONID之后再提交给服务端的时候,服务端就能知道:哦,原来你就是上次来请求过我的那个人;我记得你在我这边喝了一杯咖啡还没付钱呢。

 

那么JSESSIONID从服务端写到客户端有两个步骤,A和B,服务端是如何选择用哪种方式的呢。这里就看上面贴出来的XML配置

如果 <Context cookies="false"> 那么是禁用了cookie的,表示用url rewriter的方式

否则默认都是用cookie的方式保存JSESSIONID的。

 

================ 上面讲了 服务器如何生成JSESSIONID,并且把Cookie保存到客户端 ===========

================ 下面讲服务器如何保存JSESSIONID,即会话状态 ===========

服务器保存会话有两种方式:

1,标准方式,就保存到内存里。系统一旦shutdown,全部会话忘了。你欠我一杯咖啡也忘了。

 

2,持久化保存,使得系统重启可恢复

如我上面贴出来的配置

 

  <Manager className="org.apache.catalina.session.PersistentManager" checkInterval="1" maxIdleBackup="2"> 
  <Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" 
   connectionURL="jdbc:mysql://localhost:3306/session?user=root&amp;password=hello" 
   sessionTable="session" sessionIdCol="session_id" sessionDataCol="session_data" 
   sessionValidCol="sessionValid" sessionMaxInactiveCol="maxInactive" 
   sessionLastAccessedCol="lastAccess" sessionAppCol="appName" checkInterval="1" debug="99" />
 </Manager>

当系统被正常关闭的时候,内存中的session会被保存到数据库里。

如图:


当然这里得先建好数据库。

类似:

create table tomcat_sessions (
  session_id     varchar(100) not null primary key,
  valid_session  char(1) not null,
  max_inactive   int not null,
  last_access    bigint not null,
  app_name       varchar(255),
  session_data   mediumblob,
  KEY kapp_name(app_name)
);

 

其中 maxIdleBackup 代表这个session 空闲了多少秒就会被保存到数据库里。

 详细配置参见官网:

http://tomcat.apache.org/tomcat-4.1-doc/config/manager.html

 

========================= 邪恶的分割线 ======================

二,tomcat 如何产生 一个新的session

MangerBase.java

    /**
     * Construct and return a new session object, based on the default
     * settings specified by this Manager's properties.  The session
     * id specified will be used as the session id.  
     * If a new session cannot be created for any reason, return 
     * <code>null</code>.
     * 
     * @param sessionId The session id which should be used to create the
     *  new session; if <code>null</code>, a new session id will be
     *  generated
     * @exception IllegalStateException if a new session cannot be
     *  instantiated for any reason
     */
    public Session createSession(String sessionId) {
        
        // Recycle or create a Session instance
        Session session = createEmptySession();

        // Initialize the properties of the new session and return it
        session.setNew(true);
        session.setValid(true);
        session.setCreationTime(System.currentTimeMillis());
        session.setMaxInactiveInterval(this.maxInactiveInterval);
        if (sessionId == null) {
            sessionId = generateSessionId();
        }
        session.setId(sessionId);
        sessionCounter++;

        return (session);

    }

 真正生成JSESSIONID的实现:

  /**
     * Generate and return a new session identifier.
     */
    protected synchronized String generateSessionId() {

        byte random[] = new byte[16];
        String jvmRoute = getJvmRoute();
        String result = null;

        // Render the result as a String of hexadecimal digits
        StringBuffer buffer = new StringBuffer();
        do {
            int resultLenBytes = 0;
            if (result != null) {
                buffer = new StringBuffer();
                duplicates++;
            }

            while (resultLenBytes < this.sessionIdLength) {
                getRandomBytes(random);
                random = getDigest().digest(random);
                for (int j = 0;
                j < random.length && resultLenBytes < this.sessionIdLength;
                j++) {
                    byte b1 = (byte) ((random[j] & 0xf0) >> 4);
                    byte b2 = (byte) (random[j] & 0x0f);
                    if (b1 < 10)
                        buffer.append((char) ('0' + b1));
                    else
                        buffer.append((char) ('A' + (b1 - 10)));
                    if (b2 < 10)
                        buffer.append((char) ('0' + b2));
                    else
                        buffer.append((char) ('A' + (b2 - 10)));
                    resultLenBytes++;
                }
            }
            if (jvmRoute != null) {
                buffer.append('.').append(jvmRoute);
            }
            result = buffer.toString();
        } while (sessions.containsKey(result));
        return (result);

    }

 当然上面那个MangerBase是个抽象类,他有各种子类:

比如:DeltaManager.java实现了分布式集群中session的拷贝。

 /**
     * create new session with check maxActiveSessions and send session creation
     * to other cluster nodes.
     * 
     * @param distribute
     * @return The session
     */
    public Session createSession(String sessionId, boolean distribute) {
        if ((maxActiveSessions >= 0) && (sessions.size() >= maxActiveSessions)) {
            rejectedSessions++;
            throw new IllegalStateException(sm.getString("deltaManager.createSession.ise"));
        }
        DeltaSession session = (DeltaSession) super.createSession(sessionId) ;
        if (distribute) {
            sendCreateSession(session.getId(), session);//拷贝到集群其他机器
        }
        if (log.isDebugEnabled())
            log.debug(sm.getString("deltaManager.createSession.newSession",session.getId(), new Integer(sessions.size())));
        return (session);

    }

 当然我们可以有我们自己的实现把session放到 memcached或者数据库里来解决集群问题。

 

 

 

  • 大小: 21.9 KB
分享到:
评论

相关推荐

    Tomcat集群——使用MSM管理集群Session

    【标题】:“Tomcat集群——使用MSM管理集群Session” 在分布式系统中,尤其是在基于Java的Web应用中,实现session的共享是确保用户状态在不同服务器之间无缝切换的关键。Tomcat,作为流行的开源Servlet容器,提供...

    Memcached-Session-Manager多tomcat实现session共享配置

    Memcached-Session-Manager是解决这个问题的一个优秀解决方案,它允许我们将用户的Session数据存储在内存缓存系统——Memcached中,从而实现跨Tomcat实例的Session共享。下面将详细介绍Memcached-Session-Manager的...

    redis-tomcat8以上集群所需要的jar :tomcat-redis-session-manager-master 等

    首先,我们来看标题和描述中提到的关键组件——`tomcat-redis-session-manager`。这是一个专门设计用于Tomcat的Redis Session Manager,它允许你在多个Tomcat实例之间共享Session数据。当你的应用程序部署在多个...

    session共享方案(tomcat8+redis共享session)

    本文将深入探讨一种实现方式——使用Tomcat8与Redis相结合的Session共享方案。该方案旨在确保用户在集群中的任意一台服务器上登录后,其Session信息能够在其他服务器上无缝访问,从而提供一致的用户体验。 首先,...

    tomcat8-session-jars.zip

    总结一下,这个压缩包提供的jar文件是解决Tomcat8集群环境下的session共享问题的关键,它支持两种流行的分布式缓存解决方案——Memcache和Redis。开发者可以根据实际需求和环境,选择合适的方式实现session的高效、...

    tomcat之间session共享之memcached方式.zip

    本资料“tomcat之间session共享之memcached方式”正是解决这个问题的一个方案,它利用了高效、流行的缓存系统——Memcached。 Memcached是一种高性能、分布式的内存对象缓存系统,广泛用于加速动态Web应用程序。在...

    tomcat-redis-session共享

    然而,这又带来了新的问题——如何在多个服务器之间共享用户的会话(session)数据?传统的基于每台服务器本地存储的session机制不再适用。为了解决这个问题,一种常见的解决方案是使用集中式的session存储服务,如...

    tomcat-redis-session-manager-master文档

    而本文将详细介绍使用Redis作为共享存储的方案——`tomcat-redis-session-manager`。 #### 必要环境准备 为了顺利实施这一方案,首先需要准备以下环境: - **Java版本**:Java 1.7 或更高版本。 - **Tomcat版本**...

    nginx_tomcat_redis搭建负载均衡共享session

    在IT行业中,构建高效、可扩展的Web服务是至关重要的,而"nginx_tomcat_redis搭建负载均衡共享session"这个主题则聚焦于如何利用这三个组件——Nginx、Tomcat和Redis来实现这一目标。Nginx是一款高性能的反向代理...

    SpringBoot集成Spring Security登录管理 添加 session 共享【完整源码+数据库】

    我们将基于给定的标签——SpringBoot、SpringSecurity、mysql、session共享和idea来构建一个完整的示例。 首先,SpringBoot是一个轻量级的Java框架,它简化了创建独立的、生产级别的基于Spring的应用程序。通过内置...

    memcached session manager 1.9.6_for_tomcat8.zip

    Memcached Session Manager是一款针对Tomcat应用服务器的会话管理器,它将Web应用程序的会话数据存储在分布式内存缓存系统——Memcached中,以提高性能和可扩展性。在Tomcat 8这个流行的Java Servlet容器中集成...

    TomcatServer.rar

    6. **集群和负载均衡**:Tomcat支持集群配置,通过复制session和负载均衡策略,可以实现高可用性和故障切换。 7. **与Spring Boot集成**:现代开发中,Tomcat常作为Spring Boot的内置服务器,简化了部署过程,同时...

    JAVA的hibernate手动获取session的方法

    首先,理解Hibernate的核心组件——Session。Session是Hibernate中的工作单元,它是与数据库交互的主要接口,负责保存、更新和删除对象,同时提供查询功能。在Java应用中,我们需要先初始化SessionFactory,然后通过...

    memcached-session-manager-1.6.5.rar

    Memcached Session Manager 1.6.5是一款专门用于处理Web应用程序中的用户会话管理的工具,它基于Java平台,利用了高效的分布式缓存系统——Memcached。在Java Web开发中,会话管理是不可或缺的一部分,而传统的基于...

    tomcat-redis-session-manager-1.2-tomcat-7:tomcat-redis-session-manager-1.2-tomcat-7

    会话被实现为非粘性的——也就是说,每个请求都能够到达集群中的任何服务器(与 Apache 提供的 Tomcat 集群设置不同。) 会话在创建后立即存储到 Redis 中以供其他服务器使用。 会话直接从 Redis 请求加载(但在...

    深入剖析tomcat (完整目录)

    - 关注Tomcat的新版本特性,例如Tomcat 9引入的HTTP/2支持,以及对Java EE 8的兼容性。 通过这份“深入剖析Tomcat”的完整目录,开发者可以从基础到高级,全方位掌握Tomcat的使用技巧和最佳实践,为构建稳定、高效...

    tomcat6源码分析

    Tomcat6支持会话管理,通过Session对象存储用户会话信息。当客户端发送带有会话ID的请求时,Tomcat会查找对应的会话,并在必要时进行会话创建、更新、销毁等操作。 五、线程模型 Tomcat6采用多线程模型处理请求,每...

    【完整源码+数据库】 SpringBoot集成Spring Security登录管理 添加 session 共享

    我们将基于给定的标签——SpringBoot、SpringSecurity、mysql、session共享和idea来构建一个完整的示例。 SpringBoot是一个轻量级的Java框架,它简化了创建独立的、生产级别的基于Spring的应用程序。通过内置的...

    apache-tomcat-8.0.zip

    在描述中提到的"Apache-Tomcat8.0版本下载",这意味着我们将探讨的是Tomcat 8.0系列的特定版本——8.0.9。这个版本可能包含了自8.0主线发布以来的一些安全更新、性能改进以及bug修复。 1. **安装与配置**: - 解压...

    httpSession

    6. **源码解析**:深入到具体的Web容器(如Tomcat、Jetty)的源代码中,理解它们如何处理session的创建、存储和销毁。 7. **工具使用**:可能介绍了一些辅助管理session的工具或库,如使用浏览器开发者工具查看...

Global site tag (gtag.js) - Google Analytics