avatar

如何实现分布式session(理论)

分布式session-理论解决思路

为什么需要分布式session?

首先聊聊session和cookie,session对象存储在服务器端节点内存中,cookie存储在客户端浏览器中。一般是客户端请求服务器,服务器端生成session对象,将session对象存储在jvm内存中,并且在响应头中放入sessionId响应给客户端,客户端收到响应后,将sessionid存储在本地。当浏览器第二次请求时会将本地cookie中存储的seesionId通过请求头的方式传递给服务器,这样服务器和客户端就能保持会话信息啦!如下图

生成cookie

image-20200719122631443

有cookie后,每次向服务器发送请求都会带上cookie

image-20200719122841887

简而言之,

当有一台服务器时,用户登录 成功后,服务器生成session将用户信息存放其中,并且以sessionid的形式返回给客户端存放在cookie中(sessionid和服务器生成的session对应), 以后客服端每次访问时,都会在cookie中携带这个sessionid,当服务端收到请求时,如果请求中包含了这个sessionid,则会把session检索出来,此时服务器getSession的就是客服端对应的session,这样就形成了一个会话。

那么为什么会出现分布式session问题呢,为了提高服务器端的负载能力,后台一般将服务器节点做集群,通过ngnix通过轮询的方式转发到目标服务器。打个比方,当浏览器首次访问A服务器生成session对象,然后在访问生成的session对象,如果正好被ngnix转发到了A服务器,那么没问题可以获取到session对象,如果不巧请求被转发到B服务器,由于之前生成的session对象在A服务器,B服务器根本没有生成session对象,很自然访问不到session对象。

理论解决思路

通过上文后,相比大家都对session和cookie有了一定的了解。

上述的问题在于 session只能存在一台服务器上,无法实现共享。

如果不将session信息存储在jvm内存上,而是放在Redis中,是不是就可以达到共享了呢?

我们模仿session的机制,使用token代替sessionid,

当用户发起登录请求成功后,随机生成一个token,使用token为key将用户信息存放在Redis中,然后生成一个cookie存放token。当用户发起请求时都会携带这个token过来,我们获取这个token,从redis中查找用户信息。

这样实现了一个分布式session(共享session)

token就是sessionid,redis相当于session,使用token从redis中获取用户信息,相当于通过sessionid获取到session中的用户信息。

参考

分布式session共享解决方案(知乎)-一叶知秋

文章作者: Hobo
文章链接: https://hobo-clh.github.io/2020/07/19/%E5%88%86%E5%B8%83%E5%BC%8Fsession/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hobo's blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论