会话管理(cookie和session)

HTTP是无状态的

     同一个浏览器访问同一个服务器可以发送多个请求。但是多个请求之间没有任何的关系!(从服务器角度来说,即使你是来自于同一个地方,我还是把你当作陌生人。)这就带来了一个问题,用户没有办法在同一个网站中进行持续的交互,比如在一个电商网站里,用户把一个鼠标加到购物车。然后切换到一个页面后又把键盘加到购物车。我们最终去结算的时候是希望鼠标和键盘是在一起的。但是默认的情况下是实现不了的,因为服务器认为两次请求是没有任何关系的。

Cookies可以解决这个问题。
注意:HTTP本质是无状态的,使用Cookies可以创建有状态的会话。

什么是Cookie?

Cookie

  • 是服务器发送到浏览器,并保存在浏览器端的一小块数据。
  • 浏览器下次访问该服务器时,会自动携带块该数据,将其发送给服务器。

优点:Cookies可以创建有状态的会话。
缺点:1.存放在客户端浏览器,不安全。
           2.每次发送请求都会携带cookie会对性能产生影响。

cookie图解:

会话管理(cookie和session)
cookie示例:
会话管理(cookie和session)
在客户端浏览器的响应头中找到cookie信息:
会话管理(cookie和session)
再次发送请求,会在浏览器的请求头中携带cookie信息(前提是请求的url在cookie的有路径范围内):
会话管理(cookie和session)
在服务器端可以得到请求头中的cookie信息:
会话管理(cookie和session)

什么是Session?

Session

  • 是JavaEE的标准,用于在服务端记录客户端信息。
  • 数据存放在服务端更加安全,但是也会增加服务端的内存压力。

为什么说Session是依赖于Cookie的?
     客户端浏览器和服务器之间可以是一对多的关系,每发送一次请求都可以在服务端创建一个Session。但是服务器不知道哪个请求对应哪一个Session。所以服务器可以创建一个cookie,并在cookie中携带SessionID来解决这个问题。图示:
会话管理(cookie和session)
Session示例:
会话管理(cookie和session)
在浏览器的响应头查看session:
会话管理(cookie和session)
因为每次发送请求都会携带cookie信息(cookie中携带了sessionId),所以可以在服务器直接获取session信息。
会话管理(cookie和session)

Session在分布式中存在的问题及解决方案:

     如下图,我们发送了一次请求,1号服务器接收到了请求并且创建了session。我们在发送一次请求,此时1号服务器不空闲,3号服务器空闲,处理了我们的请求,但是3号服务器里没有1号服务器中的那个session,所以又重新创建了一个session。
会话管理(cookie和session)
解决方案:
1.黏性session
    当一个请求通过nginx发送给1号服务器后,下次这个请求再来,还发送给1号服务器。

缺点:负载不均衡

2.同步session
    当一个服务器接收到请求创建session后,会把这个session同步到其他的服务器。

缺点:1.性能下降。(因为session要同步给多台服务器)
           2.服务器之间产生耦合。
会话管理(cookie和session)
3.共享session
    单独搞一台服务器来存放session,其他服务器都来请求这台服务器。
缺点:这台服务器一旦挂掉就完了。如果对它再部署集群又回到了最初的问题。
会话管理(cookie和session)
4.主流解决方案
    能用cookie就用cookie,如果真的要用session,就把session存在redis中,并做集群。
会话管理(cookie和session)