博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Session
阅读量:6497 次
发布时间:2019-06-24

本文共 3963 字,大约阅读时间需要 13 分钟。

hot3.png

概述

Session是服务器端使用的一种记录客户端状态的机制,如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

Session原理

Session是基于Cookie来工作的,同一个客户端每次访问服务器时,只要当浏览器在第一次访问服务器时,服务器设置一个id并保存一些信息(例如登陆就保存用户信息,视具体情况),并把这个id通过Cookie存到客户端,客户端每次和服务器交互时只传这个id,就可以实现维持浏览器和服务器的状态,而这个ID通常是NAME为JSESSIONID的一个Cookie。如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了其它多种实现方式。

Session实现方式

通过URL传递SessionID

如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:。的原理是将该用户Session的id信息重写到URL地址中,即在文件名的后面,在URL参数的前面添加了字符串“;jsessionid=XXX”,其中XXX为Session的id。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。

通过Cookie传递SessionID

通过SSL传递SessionID

根据javax.servlet.request.ssl_session属性值设置SessionID。

通过隐藏表单传递SessionID

表单隐藏字段,就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

session生命周期

在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”。对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个 session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。

恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。

session在下列情况下被删除

  • 程序调用HttpSession.invalidate()
  • 距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
  • 服务器进程被停止

与Cookie区别

  • cookie数据存放在客户的浏览器上,session数据放在服务器上,但是服务端的session的实现对客户端的cookie有依赖关系的;
  • cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session;
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用COOKIE;
  • 单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能超过3K;

跨窗口会话跟踪

通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了,此时我们可以先把sessionid保存在persistent cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent cookie的结合我们就实现了跨窗口的session tracking()。

分布式Session管理

      Web应用在单机部署的情况下,Session是被单个应用服务器存储管理的,由于只有一个应用服务器,用户的所有请求都是通过它进行响应处理的,所以能够很容易实现会话跟踪和保持。随着业务量的增长,系统架构需要做出调整以适应发展的需要,可能会使用分布式架构或微服务架构,无论使用哪种架构方式,应用系统单机部署的模式已经不能满足需求,所以会将应用系统部署到多台应用服务器上,用户的请求也会通过负载均衡转发到某个具体应用服务器上执行,可能会出现在A1系统登录后创建并保存Session,再次发起请求,请求被转发到A2系统上显示未登录的情况,此时单机部署模式下的Session机制已不能满足要求。所以,在分布式架构或微服务架构下,必须保证一个应用服务器上保存Session后,其它应用服务器可以同步或共享这个Session。

关于有状态服务和无状态服务

有状态和无状态服务是两种不同的服务架构,两者的不同之处在于对于服务状态的处理。服务状态是服务请求所需的数据,它可以是一个变量或者一个数据结构。无状态服务不会记录服务状态,不同请求之间也是没有任何关系;而有状态服务则反之。

典型的无状态服务的例子就是Http协议。例如,要实现一个计算求和的服务,每次请求都将求和的两个值传送给服务端,然后服务端计算求和结果,并返回给客户端,服务端不保存任何信息,这样的服务就属于无状态服务。有状态服务则相反,服务会存储请求上下文相关的数据信息,先后的请求是可以有关联的。在Web 应用中,经常会使用Session来维系登录用户的上下文信息。虽然Http协议是无状态的,但是借助于Cookie和Session,可以使http服务转换为有状态服务。

无状态的服务很容易横向扩展,只需要在负载均衡之后增加节点就可以处理更多请求,同时具有更好的维护性和容错性(倘若有状态,若保有用户信息的服务器宕机,那么该用户最近的所有交互操作将无法被透明地移送至备用服务器上,除非该服务器时刻与主服务器同步全部用户的状态信息)。但是无状态服务也不是完美无缺的,其中一个缺点就是和数据层之间的请求延迟,以及为了解决这种延迟增加缓存所带来的复杂性和一致性问题最理想的状态存放点,要么在最前端,要么在最底层的存储层。只有将 IO 密集型程序和CPU密集型程序分离,才是通往“无状态”真正的出路。一旦分离后,CPU 密集型的程序自然就是“无状态”了。如此也能更好的做“弹性扩容”。因为常见的需要“弹性扩容”的场景一般指的就是 CPU负荷过大的时候。

Session复制

在支持Session复制的Web服务器上,通过修改Web服务器的配置,可以实现将Session同步到其它Web服务器上,达到每个Web服务器上都保存一致的Session。

优点:代码上不需要做支持和修改。
缺点:需要依赖支持的Web服务器,一旦更换成不支持的Web服务器就不能使用了,在数据量很大的情况下不仅占用网络资源,而且会导致延迟。
适用场景:只适用于Web服务器比较少且Session数据量少的情况。
可用方案:开源方案tomcat-redis-session-manager,暂不支持Tomcat8。

Session粘滞

将用户的每次请求都通过某种方法强制分发到某一个Web服务器上,只要这个Web服务器上存储了对应Session数据,就可以实现会话跟踪

优点:使用简单,没有额外开销。
缺点:一旦某个Web服务器重启或宕机,相对应的Session数据将会丢失,而且需要依赖负载均衡机制。
适用场景:对稳定性要求不是很高的业务情景。

Session集中管理

在单独的服务器或服务器集群上使用缓存技术,如Redis存储Session数据,集中管理所有的Session,所有的Web服务器都从这个存储介质中存取对应的Session,实现Session共享,通过剥离session,将一个有状态服务转换成无状态服务,相对来说,Session集中管理更加可靠,使用也是最多的

优点:可靠性高,减少Web服务器的资源开销。
缺点:实现上有些复杂,配置较多。
适用场景:Web服务器较多、要求高可用性的情况。
可用方案:开源方案Spring Session,也可以自己实现,主要是重写HttpServletRequestWrapper中的getSession方法。

基于Cookie管理

这种方式每次发起请求的时候都需要将Session数据放到Cookie中传递给服务端

优点:不需要依赖额外外部存储,不需要额外配置。
缺点:不安全,易被盗取或篡改;Cookie数量和长度有限制,需要消耗更多网络带宽。
适用场景:数据不重要、不敏感且数据量小的情况。

参考链接

转载于:https://my.oschina.net/u/2939155/blog/3037540

你可能感兴趣的文章
Java WEB开发时struts标签 显示set内容
查看>>
spring-data-elasticsearch 概述及入门(二)
查看>>
Solr启动和结束命令
查看>>
1.12 xshell密钥认证
查看>>
3.2 用户组管理
查看>>
awk
查看>>
AliOS Things SMP系统及其在esp32上实现示例
查看>>
VMware虚拟机出现“需要整合虚拟机磁盘”的解决方法
查看>>
ibatis 动态查询
查看>>
汇编语言之实验一
查看>>
09、Modules - Directory根据目录加载模块文件
查看>>
观影识人生
查看>>
The Little Prince-12/12
查看>>
git 调用 Beyond Compare
查看>>
ECMAScript 5 —— Function 类型 (一)
查看>>
SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]
查看>>
android实现图片识别的几种方法
查看>>
bzoj1030[JSOI2007]文本生成器
查看>>
mvc学习地址
查看>>
masonry 基本用法
查看>>