Session详解

1、什么是Session?

Session被翻译为会话,其本来的含义就是指有始有终的一系列动作/消息,比如打电话时从拿起电话到挂断电话这中间的一系列过程可以被称为一个Session。有时候我们可以看到这样的话“在一个浏览器会话期间,……”,这里的会话一词用的就是其本义,是指从一个浏览器窗口打开到关闭这个期间。最让人歧义的就是“用户(客户端)在一次会话期间”这样一句话,它可能只用户的一系列动作(一般情况下是同某个具体目的相关的一系列动作,比如从等候操作,到登出这样一个网上购物的过程),有时候也可能仅仅是指一次连接。

然而当Session一次与网络协议相关联时,它又往往隐含了“面向连接”和/或“保持状态”这两个含义,“面向连接”指的是在通信双方在建立一个通信的渠道,如打电话,知道对方接了电话通信才能开始,与此相对的是写信,在你把信发送出去的时候,你并不能确认对方的地址是否正确,通信渠道不一定能建立,但对发信人来说,通信已经开始了。“保持状态”则是指通信的一方能够把一系列的消息关联起来,使得消息之间可以互相依赖。

而到Web服务器蓬勃发展的时代,Session在Web开发语境下有了新的扩展,它的含义是指一类用来在客户端与服务器之间保持状态的解决方案。由于各种用于Web开发的语言在一定程度上都提供了对这种解决方案的支持,所以在某种特定语言的语境下,Session也被称为用来指代该语言的解决方案,比如经常把Java里提供的javax.servlet.http.HttpSession简称为session。

2、为什么有Session?

首先大家知道,HTTP协议时无状态的,即用户连续访问某个网页100次和访问1次对服务器来说是没有区别的,因为服务器无法记住用户。

那么,在一些场合下,确实需要服务器记住当前用户怎么办?比如用户登录邮箱后,接下来要收邮件、写邮件、总不能每次操作都让用户如用户名和密码吧,为了解决这个问题,Session的方案就被提出来,事实上Session并不是什么新技术,而且也不能脱离HTTP协议以及任何现有的Web技术。

3、如何实现Session?

Session原理其实很简单,假如用户访问网页时就像逛澡堂,第一次进去用户是没有钥匙的,这个时候用户交了钱,服务台就分配一把钥匙给用户,用户走到哪里就要带上,因为这是用户身份的唯一标识,接下来就用这把钥匙可以去打开一个专有的储物柜存储衣物,洗完澡后,在用钥匙去打开柜子拿出衣物,最后离开游泳池时,把钥匙归还,整个洗澡过程就是一次Session(会话),在这个例子中,钥匙就是Session中的Key,而储物柜可以理解为存储用户会话信息的介质。

那么在Web服务器中如何实现Session呢?通过上面的例子会较容易理解,主要解决两个问题,一个是钥匙的问题,一个是存储用户信息的问题。对于第一个问题,即什么东西可以每次请求都会自动带到服务器呢?如果比较了解HTTP协议,那么答案一目了然,就是Cookie,如果想为用户建立一次会话,可以在用户授权成功时返回一个Cookie,叫做会话ID,该ID当然是惟一的,比如PHP就会为建立会话的用户默认设置一个名为PHPSESSID,值可以看做为一个随机字符串的Cookie,如果用户再次操作或访问携带了这个Cookie,服务器就能识别为刚访问的用户。

4、如何实现Session共享

首先应该明白,为什么要事先共享,如果某个网站是存在一台机器上,那么是不存在这个问题的,因为会话数据就在这台机器上,但是如果使用了负载均衡的方式把请求分发到不同的机器上呢?这个时候会话ID在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的Session数据可能存在其中的一台机器上,这个时候就会出现读取不到Session数据情况,于是就需要实现Session共享。

事实上,各种Web框架早已考虑到这个问题,比如ASP.NET,是支持通过配置文件修改Session的存储介质为SQL Server的,所有机器的会话数据都从同一个数据库读,就不会存在不一致的问题;PHP支持把会话数据存储到某台Memcache服务器上,也可以手工吧Session文件存放的目录改为NFS网络文件系统,从而实现文件的跨机器共享。

还有一个简单的办法可以用于会话信息不会频繁变更的情况,在机器A设置用户会话的时候,把会话数据POST到机器B的一个cgi(接口协议,Web服务器运行外部程序的规范,其结构如图1所示。),机器B的CGI把会话数据存下来,这样机器A和B都会有一份Session数据的备份。

5、Session存储

5.1 PHP中的Session存储

默认情况下,php.ini中设置的SESSION保存方式是files(session.save_handler=files),即使用读写文件的方式保存SESSION数据,而SESSION文件保存的目录由“session.save_path”指定,文件名以“sess_”为前缀,后跟SESSION ID,如“sess_c72665af28a8b14c0fe11afe3b59b51b”。文件中的数据即是序列化之后的SESSION数据了。

如果访问量较大,可能产生的SESSION文件会比较多,这时可以设置分级目录进行SESSION文件保存,效率会提高很多,设置方法为:“session.save_path=”N;/save_path””,N为分级的级数,save_path为开始目录。

当写入SESSION数据的时候,PHP会获取到客户端的SESSION_ID,然后根据这个SESSION ID到指定的SESSION文件保存目录中找到相应的SESSION文件,不存在则自行创建,最后将数据序列化写入文件。读取SESSION数据也是类似的操作流程,对读出来的数据需要进行解序列化,生成相应的SESSION变量。

对PHP而言将数据序列化保存在文件中,内容如下所示,如图2所示。

security_code|s:4:"chvw";userID|s:1:"1";userName|s:13:"administrator";userPassword|s:32:"5128c67cc3518cf03ad39c622426bb8c";userRole|s:15:"1,2,3,4,5,6,7,8";realName|s:15:"超级管理员";photo|N;visitCount|i:54;preLoginIP|s:9:"10.10.0.1";nowLoginIP|s:9:"10.10.0.1";preLoginTime|s:10:"1523848620";nowLoginTime|s:10:"1523855610";

5.2 JAVA中的Session存储

SESSION ID是一个会话的Key,浏览器第一次访问服务器会在服务器端生成一个SESSION,有一个SESSION ID和它对应。Tomcat生成SESSIONID叫做jsessionid。

SESSION在访问Tomcat服务器HttpServletRequest的getSession(true)的时候创建,Tomcat的ManageBase类提供创建SESSION ID的方法:随机数+时间+jvmid。

存储在服务器的内存中,Tomcat的StandardManager类将Session存储在内存中,也可以持久化到File、数据库、Memcache、Redis等。客户端只保存SESSION ID到Cookie中,而不会保存SESSION。SESSION销毁只能通过invalidate或超时,关掉浏览器并不会关闭SESSION。

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值