面试知识点学习5——HTTP的无状态性 、Cookie 、Session原理 Session共享

参考资料:

(2条消息) JavaWeb基础系列(四)Session和Cookie_小刺猬喜歡獨角獸-CSDN博客

什么是Http无状态?Session、Cookie、Token三者之间的区别 - 翎野 - 博客园 (cnblogs.com)

Java面试高级篇—Session和Cookie的区别与联系面试题12期 - yoodb - 素文宅博客

集群间如何实现session共享【面试+工作】 - 云+社区 - 腾讯云 (tencent.com)

5.1 无状态的含义

协议对于事务处理没有记忆功能。缺少状态意味着,假如后面的处理需要前面的信息,则前面的信息必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要前面信息时,应答就较快。

直观地说,就是每个请求都是独立的,与前面的请求和后面的请求都是没有直接联系的。

为什么不改进http协议使之有状态:

最初的http协议只用来浏览静态文件的,无状态协议已经足够,这样实现的负担很轻。

随着web的发展,它需要变得有状态,但是不需要修改http协议使之有状态。因为我们经常长时间逗留在某一个网页,然后才进入到另一个网页,如果在这两个页面之间维持状态,代价很高。

5.2 cookie和session技术 ——会话技术

HTTP本身是一个无状态的连接协议,为了支持客户端与服务器之间的交互,我们引入会话技术为交互存储状态,会话技术分为Cookie和Session。

会话技术定义:

    从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,称为一次会话。

会话技术就是记录这次会话中客户端的状态与数据的。

5.2.1 Cookie

  • 将用户的数据存储到客户端,减少服务器端的存储的压力,安全性不好,客户端可以清除cookie。
  • Cookie具有不可跨域名性,即浏览器访问不同的域名只会携带该域名对应的Cookie,某一域名也只能操作该域名的Cookie。

    Cookie在客户端由浏览器来管理,浏览器能够保证Cookie的不可跨域名性,从而保证用户的隐私安全。

  • 工作原理:给每个客户端颁发一个通行证,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份。
  • 实现方法:把登录信息如账号、密码等保存在Cookie中,并控制Cookie的有效期,下次访问时再验证Cookie中的登录信息即可。
  • 实现方案:

    • 方案一:最直接的是把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中。 很危险
    • 方案二:把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。这种方案略微安全一些。如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。 仍然危险
    • 方案三:只在登录时查询一次数据库以后访问验证登录信息时不再查询数据库

      本方案把账号保存到名为account的Cookie中,把账号连同密钥用MD5算法加密后保存到名为ssid的Cookie中。只需验证account账号与密钥加密后,是否与ssid相等。

      该加密机制中最重要的部分为算法与密钥。由于MD5算法的不可逆性,即使用户知道了账号与加密后的字符串,也不可能解密得到密钥。因此,只要保管好密钥与算法,该机制就是安全的。

5.2.2 Session

  • 将数据存储在服务器端,安全性相对好,占用服务器资源,增加服务器的压力;
  • 原理: 为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个Session ID去服务器中寻找属于自己的内存空间。所以说Session的实现是基于Cookie,Session需要借助于Cookie存储客户的唯一性标识Session ID
  • 类比:相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
  • 创建:第一次执行request.getSession()时创建
  • 销毁:

    • 服务器(非正常)关闭时;
    • session过期/失效(默认30分钟,从不操作服务器端的资源开始计时);
  • 实现方式:

    一般浏览器提供了两种方式来保存,还有一种是程序员使用html隐藏域的方式自定义实现:

    1)使用Cookie来保存,这是最常见的方法。服务器通过设置Cookie的方式将Session ID发送到浏览器。如果我们不设置这个过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。

    如果我们设置这个时间为若干天之后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同样会发送到服务器上。

    2)使用URL附加信息的方式,也就是像我们经常看到JSP网站会有aaa.jsp?JSESSIONID=*一样的。这种方式和第一种方式里面不设置Cookie过期时间是一样的。

    3)在页面表单里面增加隐藏域,这种方式实际上和第二种方式一样,只不过前者通过GET方式发送数据,后者使用POST方式发送数据。但是明显后者比较麻烦。

5.2.3 Cookie和Session的关系

  • cookie 是一个实际存在的、具体的东西,http 协议中定义在 header 中的字段。
  • session 是一个抽象概念。开发者为了实现中断和继续等操作,将client和server之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。
  • session描述的是一种通讯会话机制,而cookie只是实现这种机制的主流方案里面的一个参与者,它一般是用于保存session ID。

5.3 Session共享

5.3.1 Session-Cookie技术运转过程

  • 用户登录时,请求到达服务器,服务器调用通过getSession()方法判断session是否存在,如果不存在,则新建session,并通过其算法为session生成一个随机数作为sessionId,开发者可在session中储存一些用户信息;

    第二次请求时,如获取用户信息,getSession()方法判断session存在,则取出session,而不是新建,从而从session中获取到用户的相关信息。

  • 客户端请求时,将cookie信息储存于request的head中发送给服务器;
  • 服务器响应时,将cookie信息置于response中回传给客户端。

5.3.2 getSession()方法做了什么

  • 第一次用户请求,客户端本地没有任何数据,即cookie为空,朝服务器发送request,getSession()中会解析request,发现其约定的cookie为null,则认为没有session,所以会重新创建一个session对象;
  • 创建session后,会将此session的id放入response中,回传给客户端,客户端则保存response中的cookie;
  • 再次请求,服务器getSession()又会重新解析request获取cookie,发现了其中的sessionId,那么根据此sessionId去服务器的中去找,则得到了上次创建的session对象,那么则认为鉴权成功
  • Java伪代码(图源见水印):

    面试知识点学习5——HTTP的无状态性 、Cookie 、Session原理 Session共享_第1张图片

5.3.3 如何实现session共享

​ 按照上面所说的session-cookie机制,session是保存在每台服务器的,但在集群中,拥有多台服务器,每台各自为政,势必会造成在这台服务器中登录,获取session成功,但是到另一台服务器上,又会获取不到session,造成鉴权失败,这样对用户来说极不友好。

  • 几种处理方式:

    • 1. 找一块公共的空间用来储存session,而不是将session储存在集群节点的某台服务器上,此时,每一台服务器都能访问这块空间,从而实现session共享;
    • 2. 采用一种同步机制实时同步每一台服务器的session信息;
  • 实现方案:

    • 持久化session到数据库,即使用数据库来储存session。数据库正好是我们普遍使用的公共储存空间,例如使用mysql数据库。

      优点:就地取材,符合大多数人的思维,使用简单,不需要太多额外编码工作

      缺点:对mysql性能要求较高,访问mysql需要从连接池中获取连接,又因为大部分请求均需要进行登录鉴权,所以操作数据库非常频繁,当用户量达到一定程度之后,极易造成数据库瓶颈,不适用于处理高并发的情况。

    • 使用redis共享session。redis是一个key-value的储存系统。可以简单的将其理解为一个数据库,与传统数据库的区别是,它将数据储存于内存中,并自带有内存到硬盘的序列化策略,即按策略将内存中的数据同步到磁盘,避免数据丢失,是目前比较流行的解决方案。

      优点:无需增加数据库的压力,因为数据存储于内存中,所以读取非常快,高性能,并能处理多种类型的数据。

      缺点:额外增加一些编码,以便操作redis。

    • 使用memcache同步session,memcache可以实现分布式,可将服务器中的内存组合起来,形成一个“内存池”,以此充当公共空间,保存session信息。

      注:MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度。

      优点:数据储存在内存中,读取非常快,性能好

      缺点:memcache把内存分成很多种规格的存储块,有大有小,不能完全利用内存,会产生内存碎片,浪费资源,如果储存块不足,还会产生内存溢出

    • 使用NFS共享session。NFS是Network File Server共享服务器的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发。选择一台公共的NFS做共享服务器,储存所有session数据,每台服务器所需的session均从此处获取。

      优点:较好的实现了session共享;

      缺点:成本较高,对于个人来说难以实现。NFS依托于复杂的安全机制和文件系

你可能感兴趣的:(java)