服务器端实现原理
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直接...以上就是关于“nginx实现多个tomcat7直接session共享所需jar包”的详细解释,包括了Session共享的背景、原理以及可能的实现方法。希望这些信息能帮助你理解和解决实际问题。
在IT领域,特别是Web应用服务器的管理与优化中,Tomcat集群实现Session复制是一个关键的技术点,它确保了高可用性和负载均衡,特别是在处理大量并发请求的场景下。本文将深入探讨这一主题,涵盖其原理、配置方法以及...
"tomcat-redis-session-manager"是一个解决方案,它将用户的Session信息存储在Redis缓存服务器中,从而实现跨服务器的Session共享。本篇文章将深入探讨这个话题,包括它的原理、配置以及实际应用。 **一、Session...
下面详细讲解 Tomcat_Session 的持久化原理和实现机制。 一、Session 的使用 Session 是一种用来跟踪用户状态的机制。Servlet 容器通过在客户端浏览器中保存一个 Session ID 来跟踪 Session。调用 session.getID()...
"tomcat-session同步所需jar.rar_session集群共享_tomcat session"这个标题表明我们关注的是如何在Tomcat集群环境中实现session的共享。这涉及到多个知识点,包括session的基本概念、session复制、粘滞会话、以及...
标题 "memcached-session-manager 实现 tomcat session共享" 指的是在分布式环境中,通过 memcached-session-manager 这个工具来实现 Tomcat 应用服务器之间的 Session 共享。Session 是 Web 应用中用于存储用户状态...
本篇文章将深入探讨在Tomcat 8中通过`集群redis`实现session共享的方法。 一、session共享的重要性 在Web应用中,session是服务器端用来存储用户状态的一种机制,比如用户的登录信息、购物车内容等。在单台服务器...
在本文中,我们将深入探讨Tomcat服务器中实现Session的相关知识,这包括Session的基本概念、目的、实现机制以及通过示例进行的详细解析。 **什么是Session?** Session是Web开发中用来跟踪用户状态的一种机制。...
使用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支持集群部署,通过复制Session数据和负载均衡,实现高可用性和水平扩展。 理解Tomcat的工作原理有助于我们更好地管理和优化Java Web应用,提升服务器性能,解决运行中可能出现的问题。通过深入学习,我们...
本篇将深入探讨如何使用Memcached实现Tomcat的Session共享,并基于提供的jar文件和Tomcat的XML配置进行详细讲解。 首先,我们需要理解Memcached的工作原理。Memcached是一个基于内存的键值对存储系统,用于临时存储...
2. `tomcat-redis-session-manager.jar`:这个是Tomcat的Redis Session Manager实现,它负责在Tomcat容器内部将Session数据保存到Redis中。 安装步骤如下: 1. 下载并添加上述jar包到Tomcat的`lib`目录,确保...
本文将深入探讨如何在Tomcat中实现Session的共享,并分析其背后的原理和配置方法。 首先,我们要理解Session的基本概念。Session是Web服务器为用户创建的一段持久性存储空间,用于存储用户在访问网站期间产生的状态...
Tomcat可以通过使用一个名为`Tomcat-Redis Session Manager`的插件来实现这一功能。这个插件允许Tomcat将session序列化并存储在Redis中,然后在需要时反序列化回session对象。 实现步骤如下: 1. **安装Redis**:...
在分布式系统中,Tomcat集群是一种常见的架构模式,用于提高应用程序的可用性和可扩展性。...同时,理解负载均衡原理、分布式系统设计以及安全性问题也是至关重要的,这将有助于你构建更健壮、高效的Tomcat集群。
通过将Tomcat的Session数据序列化后存入Redis,可以实现跨服务器的Session共享,提高可扩展性和高可用性。 【三、集成Tomcat与Redis】 1. 添加依赖:首先,需要将Redis客户端的JAR包(如jedis)引入到Tomcat的lib...
Tomcat是Apache软件基金会的Java Servlet容器,它实现了Java EE中的Web应用服务器规范。深入理解Tomcat的内部原理有助于我们更好地管理和优化Web应用程序的性能。以下是对Tomcat主要组成部分的详细解析: 1. Server...
下面将详细解释这一技术的实现原理和步骤。 首先,理解Session共享的必要性。当多个服务器实例共同处理一个用户会话时,每个服务器都需要访问相同的数据,否则会导致会话状态丢失。传统的基于Cookie的解决方案不能...
《Tomcat工作原理详解》 Tomcat作为一款广泛使用的开源Java应用服务器,其工作原理是许多开发者想要深入了解的关键。本文将从多个层面深入探讨Tomcat的运作机制,旨在帮助读者全面理解其设计思想和核心功能。 一、...