Session学习小结

零、从会话技术讲起

我理解的一次会话就是打开浏览器行一系列操作(打开各种链接,访问各种页面)后,再关闭浏览器。这就叫一次会话。会话在百度百科的定义是是指一个终端用户与交互系统进行通讯的过程。也就是说,会话技术是客户端浏览器与服务器进行不断交互的过程,在这个过程中,只要有一方不关闭,就可以说是在一次会话中。会话中包含多次请求和响应。
会话技术的方式有两种:客户端会话技术cookie与服务端会话技术session。

一、什么是Session?

概念就是服务器端会话技术,在一次会话的多次请求间共享数据,将数据存在服务器端的对象(HttpSession)中,也就是说我们每次请求服务端,服务端就会在内存中为我们开辟一个空间,这个空间就可以叫Session。这块空间是跟浏览器息息相关的,在浏览器不关闭的情况下,我们可以正常访问。如果我们新打开一个浏览器,这个浏览器就无法正常访问了,要访问也是重新在服务端内存中开辟空间,获得对应这个浏览器的session。

获取HttpSession对象:

HttpSession session = request.getSession()

对HttpSession对象的一些操作:

Object getAttribute(String name);
void setAttribute(String name, Object value);
void removeAttribute(String name);

此外,HttpSession还定义了一个invalidate的方法,该方法会强制会话过期,并且清空其保存的对象。默认情况下,HttpSession会在用户不活动一段时间后自动过期。我们可以动过调用HttpSession的serMaxInactiveInterval来单独的对某个HttpSession来设置其超时时间:

void setMaxInactiveInterval(int seconds);

如果传入的参数为0,则该HttpSession永不过期(这并不是一个好的设计方法,这么设计的话该HttpSession所占用的堆内存将永不释放,直到应用重新加载或者Sevlet容器关闭)。

二、Session的一些细节

1、当客户端关闭后,服务器不关闭,两次获取的session是否为同一个?
答:默认情况下不是的,如果要期望客户端关闭后session也能为相同的,我们可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。(实际上就是将session以cookie的形式存起来了)

Cookie cookie = new Cooke("JSESSIONID", session.getId());
cookie.setMaxAge(60*60*24*30);
response.addCookie(cookie);

2、客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
答:肯定也不是同一个,服务器关闭后,session对象随即被销毁,下次在启动创建的时候,地址不是同一个,下次创建分配地址的时候,很难做到地址相同。如果我们要确保服务器关闭后原session还在,数据不流失,我们可以将session钝化(即在服务器正常关闭前,将session对象序列化到硬盘上),然后在将session活化(在服务器启动后,将session文件转化为内存中的session对象即可)。


3、session的失效时间?

  • 服务器关闭,session被销毁。
  • 调用其invalidate()方法,自行销毁。
  • session的默认失效时间为30min,我们可以在tomcat下的web.xml中设置session-config来确保其最大存活时间。

4、我们如何知道这个session就对应的这个浏览器呢,怎么保证浏览器不去访问其他的session呢?
答:当我们访问一个页面的时候,服务端会给这个浏览器创建一个独一的号码,同时也给创建的session同样的号码,这样我们用这个浏览器访问该页面的子页面的时候,就会可以获取到主页面的session信息。这个号码叫做jsessionID

三、Session的实现方式

第一种使用cookie的方式实现
如果浏览器支持的话,我们可以把sessionID放在cookie里面。cookie有临时的也有定时的。临时的就是浏览器关闭然后cookie消失,正好符合session的理念。保存在cookie里的jsessionID是独一无二的。
第二种使用URL重写的方式实现
如果浏览器不支持cookie,我们只能自己手动编程重写URL来实现session。我们可以使用一个方法response.encodeURL()
该方法有两个作用:一是转码(转中文或者其他特殊字符的编码),二是在URL后面加上jsessionID。
若想使程序永远支持session,那就加上encodeURL,这样即使别人禁用了cookie,我们也一样可以使用session。

四、Session的特点以及与Cookie的对比

1、session是用于存储一次会话的多次请求数据,它是存在服务器端的。
2、session可以存储任意类型,任意大小的数据。
3、与cookie对比:session存储数据在服务器端,而cookie在客户端;session没有数据大小限制,cookie有;session数据安全,而cookie相对不太安全。

五、Session跨域

什么是session跨域?
Session跨域就是摈弃了系统提供的Session,而是用自定义的类似Session的机制来保存客户端数据的一种解决方案。
如:通过设置cookie的domain来实现cookie的跨域传递。在cookie中传递一个自定义的session_id。这个session_id是客户端的唯一标记,将这个标记作为key,将客户端需要保存的数据作为value,在服务端进行保存,这种机制就是Session的跨域解决。
相关概念解释:

  • 跨域:客户端请求的时候,请求的服务器不是同一个IP、端口、域名、主机名的时候都称为跨域。
  • 域:一个完整的,有独立访问路径的功能集合称为一个域。如:百度称为一个应用或系统。百度下有若干的域,如搜索,贴吧等。
  • 域信息:有时也称为多级域名。域的划分:以IP、端口、域名、主机名为标准进行划分。不同的域有不同的cookie信息

解决方案:
1、session sticky:会话保存在单机上,保证会话请求落在同一台服务器上。
采用源地址哈希法进行负载均衡(根据获取客户端的ip地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号),同一ip地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

这种方法存在的问题是:如果一台web服务器宕机或者重启,那么这台机器上保存的会话数据都会丢失,会造成用户之前的授权操作都需要再进行一次。
2、session replication:session复制,每一台服务器上都保持一份相同的session(造成额外的存储开销和网络开销)
session复制,通过相关技术实现session复制,使得集群中的各个服务器相互保存各自节点存储的session数据。tomcat本身就可以实现session复制的功能。
这种方法存在的问题是:

  • 同步session数据会造成网络开销,随着集群规模越大,同步session带来的带宽影响也越大。
  • 每个节点需要保存集群中所有结点的session数据,就需要比较大的内存来存储。

3、session集中存储:存储在db、缓存服务器(redis)
4、使用cookie跨域共享

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章