有史以来最装逼的方式描述Session

第一章 初入中国

大家都知道奥巴马吧,他前几天跟我说他在美国呆腻了想来中国发展一下,但是奥巴马在北京没有房产,于是只能睡酒店,而且入住酒店需要身份证,可是奥巴马没有身份证,于是他向某某部门申请了一个身份证

就是这个。

正文:这里的带身份证去酒店的事可以理解为,我们想看网页,就必须要带着网站的url(酒店地址)和SessionId(身份证号)还有一些其他信息。



第二章 回乡探亲

奥巴马想家了于是打车回到美国,在美国停留了10天后又回到中国继续北漂。当他再去那家酒店的时候,发现由于自己离开中国后身份证失效了,必须重新办一张,于是他就又搬了一个新的身份证,这次成功进入酒店。

正文:离开中国这件事可以理解为我们关闭浏览器的行为,这个时候返回中国相当于再次打开浏览器,于是再次为用户申请一个新的SessionId:

因此只要他还在中国(浏览器不关闭),他就可以使用这个身份证(SessionId)去做事了


第三章 酒店倒闭了

奥巴马之前去酒店,只需要提供身份证号,酒店就能查到奥巴马的全部信息。后来这家酒店倒闭了,奥巴马换了一个新开业的酒店,但是这个酒店使用手工记账的方式,于是每次奥巴马都需要把自己的详细信息告诉酒店服务员,进行登记。

正文:根据id查找全部信息和提供全部信息告诉酒店,就是Session和Cookie的差别。

  • cookie采用在客户端保持状态的方案,cookie的内容主要包括:名字,值,过期时间,路径和域。
  • session采用在服务器端保持状态的方案,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用

session在何时被创建:调用HttpServletRequest.getSession(true)才被创建

getSession(boolean create)意思是返回当前reqeust中的HttpSession ,如果当前reqeust中的HttpSession 为null,当create为true,就创建一个新的Session,否则返回null; 
简而言之: 
HttpServletRequest.getSession(ture)等同于 HttpServletRequest.getSession() 
HttpServletRequest.getSession(false)等同于 如果当前Session没有就为null; 


第四章 奥巴马游泳

这一天奥巴马想游泳,但是他游泳的时候只能穿游泳裤,没有办法携带身份证。游泳池老板说只要说你的身份证号就可以去游泳。于是奥巴马汇报了自己的身份证号,他如愿以偿的游泳了。


正文:有些浏览器禁用Cookie(身份证),于是请求只能将SessionId(身份证号)告诉服务器(游泳池老板),才能正常获取用户信息进而获得服务。

由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为

http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764


第五章 身份证过期了

在中国的十年岁月奥巴马的身份证终于过期了,于是他重新办了一个身份证。获得了新的Id。

正文:当sessionId到达超时时间后,原有的Sessionid将被销毁。这里的超时通常指服务器接收到客户端最近一次请求的时间。

设置Session超时时间方式:
方式一:
  在web.xml中设置session-config如下:
 <session-config>
  <session-timeout>2</session-timeout>
 </session-config>
 --即客户端连续两次与服务器交互间隔时间最长为2分钟,2分钟后session.getAttribute()获取的值为空
  session.getCreationTime()   获取session的创建时间
  session.getLastAccessedTime()  获取上次与服务器交互时间
  session.getMaxInactiveInterval() 获取session最大的不活动的间隔时间,以秒为单位120秒。
方式二:
 在Tomcat的/conf/web.xml中session-config,默认值为:30分钟
 <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
方式三:
 在Servlet中设置
  HttpSession session = request.getSession();
  session.setMaxInactiveInterval(60);//单位为秒


第六章 齐聚北京村

奥巴马玩的很high以至于默克尔,马克龙,特蕾莎梅,特朗普等100多位领导人都想来北京生活,警察蜀黍的系统没有足够的并发量支持多人查询身份信息,于是就把他们的身份信息分别存在几个服务系统中。系统记录了他们的身份证号,有效日期等。每次查询都需要用一台机器去识别他们的身份证号,以此来找到他们的身份信息所存放的那台数据库。后来特朗普带来了牛叉酷炫吊炸天的美帝核心科技,于是这些不同系统具备了交流沟通的能力,可以互相询问身份证号的信息,实时更新确保所有身份库信息都一致。又过了几天,以精准的德国工艺和强迫症似的性格理念为代表的默克尔说,所有的身份信息都应该存在一个服务器里,所有的身份信息都存在了一台数据库中,所有的并发系统都要去访问这个数据库。

正文:

集群session一致性和同步问题

问题
因为会话信息保存在单机上,当我们的应用服务器从一台变成两台后,我们就会遇到session的问题了!

当我们第一次访问网站时请求落到了A服务器,那么我的session就创建在A服务器上了,如果我们不做处理,就不能保证接下来的请求每次都落在同一台服务器上了,这就是session问题。

解决办法

1. session sticky
在web服务器变成多台后,如果我们可以保证同一个会话请求都能在同一个web服务器上处理,那么对于这个会话个体来说,和单机的情况是一样的。这就需要负载均衡器能够根据每次请求的会话标识来进行请求转发。
有何问题:
① 如果有一台web服务器宕机或重启,那么这台机器上的会话数据会丢失
② 负载均衡器变成了一个有状态的结点,要保存会话到具体web服务器的映射,要消耗一定的内存。


2. session replication
web服务器之间增加了会话数据的同步,通过同步就保证了不同web服务器之间的session数据一致,一般的应用容器都支持这种方式。
问题:
① 只要session数据有变化,就需要将数据同步到其他机器上,会带来一定的网络带宽开销
② 每台web服务器都要保存所有的session数据,如果整个集群session数很多的话,对内存资源消耗较大。
该方案不适合集群机器较多的场景。

3. session数据集中存储
把session数据集中存储起来,然后不同的web服务器从相同的地方来获取session,存储session数据的方式可以为数据库,也可以使用其他分布式存储系统。
问题:
① 获取session存在延时和不稳定性,不过我们的通信基本在内网,问题不大。
② 如果存储session的机器或集群发生问题,就会影响到应用。
当集群规模较大时,session数较多时,该方案可以考虑。


猜你喜欢

转载自blog.csdn.net/qq_31615049/article/details/80559429