Web的Session:别被SessionID弄晕,让你的数据在服务器跳舞!

深度解析Web中的Session管理机制

1. 客户端Session与服务器端Session

在Web开发中,Session是一种重要的机制,用于在客户端和服务器之间保持状态。它分为客户端Session和服务器端Session。

客户端Session在用户首次与Web服务器建立连接时生成,服务器会分发一个SessionID作为用户标识,通常是一个由24个字符组成的随机字符串。每次用户提交页面时,浏览器会在HTTP头中携带这个SessionID,以便服务器能够识别当前请求来自哪个客户端。通常,客户端Session默认以cookie形式存储在用户浏览器中,但如果用户禁用了cookie,我们可以选择将SessionID直接嵌入URL中,尽管这种方式并不常见。

2. SessionID的生成与存储

2.1 SessionID的生成

SessionID的生成由服务器负责,在用户首次访问服务器时创建。在Tomcat中,通常由ManagerBase类提供生成SessionID的方法,其生成机制包括随机数、时间和jvmid(Java虚拟机标识),确保SessionID的唯一性。

2.2 SessionID的存储

生成的SessionID通常存储在服务器的内存中。Tomcat的StandardManager类负责将Session信息存储在服务器内存中,但还有其他可选的存储方式,如持久化到文件、数据库、memcache或Redis。客户端仅保存SessionID到cookie中,而不存储Session本身。

3. Session的删除与浏览器关闭

3.1 内存中Cookie与硬盘中Cookie

Session的存储方式与Cookie的生命周期相关。浏览器中的Cookie分为内存中Cookie和硬盘中Cookie。内存中Cookie生命周期与浏览器会话期间一致,即只要关闭浏览器窗口,Cookie就会消失。硬盘中Cookie则有过期时间,即便关闭浏览器后再次打开,这些Cookie仍然有效,直到过期。

3.2 Session的删除时机

Session的删除有以下几种时机:

  • 程序调用HttpSession.invalidate(): 主动调用该方法删除Session。
  • 距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间: 当Session超过最大有效时间未被访问时,服务器自动删除Session。
  • 服务器进程被停止: 当服务器停止运行时,所有Session将被删除。

需要注意的是,关闭浏览器只会使存储在客户端浏览器内存中的session cookie失效,而不会使服务器端的Session对象失效。

4. Tomcat中Session的创建与存储

4.1 ManagerBase

ManagerBase是所有session管理工具类的基类,负责生成sessionId值的方法。生成的sessionId包括随机数、时间和jvm的id值,确保不同jvm的id值是唯一的。

4.2 StandardManager

StandardManager是Tomcat容器中默认的session管理实现类,它将session的信息存储在web容器所在服务器的内存中。

4.3 PersistentManagerBase和StoreBase

PersistentManagerBase是继承自ManagerBase的基类,它是所有持久化存储session信息的基类。PersistentManager继承了PersistentManagerBase,提供了一些额外的功能。对于持久化存储session,Tomcat还提供了StoreBase的抽象类,其中包括文件存储FileStore和数据存储JDBCStore等实现。

5. Session相关问题及解决方案

5.1 会话cookie和持久cookie的区别

如果不设置过期时间,会话cookie的生命周期为浏览器会话期间,关闭浏览器窗口即失效。持久cookie通过设置过期时间,可以在关闭浏览器后仍然有效。

5.2 保存Session ID的几种方式

  • 使用cookie: Session ID以cookie形式存储,浏览器在交互过程中自动发送给服务器。
  • URL重写: 在URL路径后附加Session ID,适用于cookie被禁止的情况。
  • 表单隐藏字段: 服务器可通过修改表单,在表单提交时将Session ID传递回服务器。

5.3 Session什么时候被创建和删除

一个常见的误解是认为Session在有客户端访问时就被创建。实际上,直到某个服务器端程序(如Servlet)调用HttpServletRequest.getSession(true)时,Session才会被创建。Session在HttpSession.invalidate()、超过最大有效时间或服务器进程停止时被删除。

5.4 getSession()/getSession(true)/getSession(false)的区别

  • getSession(): 当Session存在时返回该Session,否则新建一个Session并返回该对象。
  • getSession(true): 与getSession()相同。
  • getSession(false): 当Session存在时返回该Session,否则不会新建Session,返回null。

5.5 使用isNew来判断用户是否为新旧用户的错误做法

isNew()方法返回true表示会话尚未与客户程序(浏览器)发生任何联系。但false并不代表用户未访问过Web应用,只说明会话可能由用户之前访问的任意页面创建。更可靠的做法是检查特定的Session中是否存在特定的key,并验证其值是否正确。

5.6 Session cookie和Session对象的生命周期

用户关闭浏览器使Session cookie失效,但Session对象仍保存在服务器端。这强调了Session管理的服务器端特性。

5.7 是否只要关闭浏览器,Session

就消失了

关闭浏览器只导致浏览器端内存中的session cookie失效,而服务器端的Session对象不会因此而删除。服务器会保留Session对象,直到其非活动时间超过设定的间隔,才会将其删除。

6. Session共享问题

在多服务器部署的场景下,不同服务器上的web容器生成的SessionID是不同的,导致跨服务器的Session同步问题。典型的解决方案是使用分布式缓存技术,例如memcached和Redis。这样,Session信息的存储被独立出来,解决了Session同步的问题。

7. 解决方案技术选型

解决Session相关问题的技术方案包括:

  1. 存储独立性: Session存储应该独立于web容器,也要独立于部署web容器的服务器。
  2. 高效同步: 使用分布式缓存技术,将Session信息存储在内存中,提高效率。

深入理解和解决Session管理问题对于构建高性能、可扩展的Web应用至关重要,特别是在分布式系统和多服务器部署的情况下。通过合理的技术选型和实践,可以更好地应对Web开发中的Session管理挑战。

相关推荐
后端转全栈_小伵3 分钟前
从 Coding (Jenkinsfile) 到 Docker:全流程自动化部署 Spring Boot 实战指南(简化篇)
java·spring boot·后端·docker·自动化·集成学习
m0_7482365830 分钟前
Django 后端数据传给前端
前端·数据库·django
m0_7482517232 分钟前
Spring Boot——统一功能处理
java·spring boot·后端
余生H36 分钟前
前端Python应用指南(五)用FastAPI快速构建高性能API
前端·python·fastapi
racerun40 分钟前
Vue vuex.store mapState
前端·javascript·vue.js
2301_8010741543 分钟前
ArkTs组件(2)
开发语言·前端·华为·harmonyos
DT——1 小时前
Sass复习篇
前端·css·sass
dream21st1 小时前
从零开始采用命令行创建uniapp vue3 ts springboot项目
spring boot·后端·uni-app
m0_748251721 小时前
ollama-webui - Ollama的ChatGPT 风格的 Web 界面
前端·chatgpt
小蒜学长1 小时前
基于Spring Boot的宠物领养系统的设计与实现(代码+数据库+LW)
java·前端·数据库·spring boot·后端·旅游·宠物