有些时候对cookie和session理解比较混乱,而且颇有可能在面试的时候,也被常常提起cookie和session的区别以及使用。通过查阅一些资料,整理出如下文档java
1、cookie和session的概念面试
一、 cookieredis
当一个用户经过Http协议访问一个服务器的时候,服务器会将一些key/value这样的一些键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在相关的条件符合的状况下,浏览器再访问服务器的时候,又会把这些数据完整的带上,返回给服务器。因为HTTP协议是无状态协议,经过cookie的这种方式,服务器就能知道客户端从哪里来的。而且在一些很短的时间呢,用户的一些信息若是被频繁访问,这样服务器就能够作一些缓存等优化,保证访问的速度。apache
Http协议中并无规定相关对cookie大小等的限制,可是因为各家浏览器在实现的过程当中的不一样,cookie的大小也不一样,可是大概为4K ,大多数浏览器对每一个站点限制通常为20个cookie,当超过这个数量的时候,老的cookie将会被覆盖掉。Cookie在生成的时候,会指定一个expire的值,指定cookie的过时时间,时间超过之后,此Cookie将不能再被使用。必须生成新的cookie,在咱们访问网站的时候,一般会见到保存密码多长时间这个选项,以下图:浏览器
实际上咱们登陆的这些信息被存储到了客户端浏览器中,而后经过这个cookie来保存咱们我的的登陆信息,这样咱们在下次访问的时候就不须要再从新输入用户名和密码进行登录。可是当超过设置的expire时间之后,就没法再使用。缓存
在java程序中,咱们能够以下代码设置和使用cookietomcat
public String getCookie(Cookie[] cookies,String key){ if(cookies!=null){ for(Cookie cookie:cookies){ if(cookie.getName().equals(key)){ returncookie.getValue(); } } } retur nnull; } publicvoiddoHello(HttpServletRequest request,HttpServletResponse response){ Cookie[]cookies= request.getCookies(); StringuserName= getCookie(cookies,"username"); if(userName==null){ response.addCookie(new Cookie("username","zhangsan")); } response.getHeader("Set-Cookie"); }
Tomcat建立Set-cookie相应头的时序图安全
从以上时序图中咱们能够看出,在咱们经过response.addCooke建立多个Cookie,咱们在每次建立Cookie时,都会建立一个以name为Set-Cookie的MimeHeaders.而且在服务器返回给客户端的时候也不会对相同Header标识的Set-Cookie进行合并。Tomcat源码中能够看出,这段代码位于org.apache.coyote.http11.Http11Processor类的prepareResponse方法中。以下:服务器
Int size = headers.size(); for(int i=0;i<size;i++){ outputBuffer.setHeader(headers.getName(i),headers.getValue(i)); }
这段代码清楚的表示,在构建Http返回字节流时,是将Header中的全部项顺序的写出,没有作任何修改,因此能够想象浏览器在接受HTTP协议返回的数据时是分别解析每个Header项的。cookie
二、 session
cookie可让服务端程序跟踪每一个客户的访问,可是每次客户端的访问都必须回传这些cookie的值,若是cookie不少,这样就无形的增长了客户端与服务端的数据量传输,而Session的出现正是为了解决这个问题。
同一个客户端每次和服务端进行交互时,不须要每次都须要回传全部的Cookie的值,而只须要传回一个ID,这个ID是客户端在第一次访问服务端的时候生成的,而每一个客户端都是惟一的,这样每个客户端就生成了一个惟一的ID,客户端只须要传回这个ID就好了,这个ID一般是NAME为JSSIONID的一个Cookie.因此说Session一般是基于Cookie来工做的,固然当客户端禁用cookie的时候,还有其余的方式进行实现Session,可是就Session和Cookie的关系来讲,Session基于Cookie进行工做。
2、session的调用过程
有了Session ID 的服务端就能够建立HttpSession对象,第一次触发经过调用rquest.getSession()方法,若是当前的Session ID尚未对应的HttpSession对象,则会建立一个HttpSession对象。并将这个对象加到org.apache.catalina.Manager
的session容器中保存,Manager类将会管理全部Session的生命周期,Session过时将会被销毁,服务器关闭,Session将会被序列化到磁盘等。只要这个HttpSession对象存在,用户就能够根据SessionId来获取这个对象,也就达到了状态保持的问题。如下是Session建立的时序图
3、cookie的安全问题
虽然Cookie和Session都是能够跟踪客户端的访问记录,可是他们的工做方式显然是不一样的。Cookie经过把全部要保存的数据经过HTTP西医的头部从客户端传递到服务器,又从服务器传递给客户端,全部的数据都存储到客户端的浏览器里。因此这些Cookie数据是能够被访问到的。咱们经过Firefox是能够访问到记录到浏览器端的用户名和密码的。例如个人百度帐号,以下图:
不只能够查看Cookie,咱们甚至能够经过一些工具添加,修改Cookie,因此Cooike的安全性是不可保证的。相比较而言,Session的安全性要高不少,由于Session是将数据保存在服务端,指示经过Cookie传递一个JSESSIONID而已。因此Session更适合存储用户隐私和重要数据。
4、分布式session实现思路
在咱们应用在进行部署的时候,如今大多数状况均不是单机部署,而是进行集群的部署,可是这样会致使客户端访问的时候,若是一台服务器挂掉,这样保存在这台服务器上的session就会消失,致使客户登陆等相关信息丢失,下降了客户体验的良好性。为了解决以上问题,基本上会有下面两种思路:
在各台服务器间session复制共享
Session复制共享,主要指在集群环境下,各台应用服务器之间进行同步session,使得session保持一致。当一台服务器出现问题时候,负载均衡服务器会把请求负载到另外的一台服务器,因为每台服务器均存储全部服务器的session,这样能够保证请求的连续性。
可是这种方案会有如下不足
技术比较复杂,必须在同一种中间件中进行实现,例如tomcat
Session的复制一定会带来性能上的损失,特别是当应用服务器比较多,session存储的内容比较大时。
Session内容的序列化,会致使服务器性能降低
Session经过广播或者其余形式同步到其余服务器。不论是内网仍是外网,一样对网络会形成压力,使之成为瓶颈。
使用session服务器,基于redis等缓存服务器
这种思想是在服务器本机存储一份session,而后再在缓存服务器中存储一份session,当服务器发生故障,在本机找不到session时,能够去缓存服务器中去寻找,再复制到本地,此种为业界经常使用思路。
本文出自 “走在将来的路上” 博客,请务必保留此出处http://wtf0313.blog.51cto.com/1093061/1687219