cookie
说 session 之前一定离不开 cookie
cookie 是存储在浏览器中的一小段文本格式如:
a=xxx;b=xxxx;c=xxx
浏览器
浏览器端在发送请求时可能会带上 cookie,如下:
Request Headers
:authority: www.cnblogs.com
:method: GET
:path: /ajianbeyourself/ajax/CommentForm.aspx?postId=4900140&_=1589522080185
:scheme: https
accept: text/html, */*; q=0.01
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9,zh-TW;q=0.8
cookie: _ga=GA1.2.958031816.1554176988; __gads=ID=c05e695fe0ecf4df:T=1554176998:S=ALNI_MYjFCirz0z4LlEeAjPh8DENgWhU2w;
referer: https://www.cnblogs.com
服务端
有些 cookie 是浏览器端主动生成,然后在请求服务端时发送的,还有一些是在服务端生成然后告知给浏览器的
当服务端需要告诉浏览器存储并且往后的所有请求都带上某个 cookie 时,会在 response 中添加如下 header:
Set-Cookie:value [ ;expires=date][ ;domain=domain][ ;path=path][ ;secure]
[ ]
中的值时可选项,value
是必选的,入之前所述 value
的格式一般是 a=xxx;b=xxxx
但却不是必须的
当浏览器发现响应头中有 Set-Cookie
这个 header 那么就会把 cookie 存储,以后对该服务器的所有请求都会带上这个 cookie
session
session 是和 cookie 配合使用的,可以这么说 session 就是用一个 map 的数据结构,而 cookie 就是 key
一般用户登录后,服务器会存储一些登录信息在缓存中,然后生成一个 cookie 其实就是一个key
返回给前端,前端以后访问时会带上这个 key 其实就是带上cookie,这个是浏览器自动帮我们做了的操作
,服务端就可以对这次请求进行一些检查操作了,比如说检查用户是否已登录
session 共享
传统的 session 是直接存储在内存中的,如果是单机部署应用肯定没问题,集群就不行了
比如说小明在登录时,被负载均衡后交由 server A 处理,server A 处理后会把 session 存储在本机的内存中,然后返回登录成功
接着,小明在网站进行一些其他操作,比如说查看好友列表,此时这个请求被负载均衡器交由 server B 处理,server B 拿到 cookie,然后根据 cookie 去查找 session,肯定找不到于是就认为小明没有登录,返回 400。。
针对这种问题有很好的轮子可以解决:Spring Session
这个问题出现的根本原因是各个服务器都把 session 缓存在自己的内存中,所以只需要把 session 集中在一个地方存储就行了,Spring Session
就是这样做的。
Spring Session
常用的一种方案是把 session 存储在 redis 中,各个服务器公用同一个 redis
spring session 的原理以及设计可以看我另一篇文章
内部服务调用 session 共享
上面的问题只是解决了客户端调用服务时 session 可以共享
server A1,server A2,server A3是一个服务集群,提供相同的服务
小明登录后,请求任意一个server都没问题
现在有了新的问题,则是内部服务之间的调用,比如
有服务server A和server B,他们提供不同的服务
小明通过server A进行登录,然后查看好友列表
`查看好友列表`这个操作需要客户端调用server A,然后server A调用server B
在 server A 中肯定能够拿到小明登录后的信息,但是 server B 则不行。
解决办法很简单,如下:
- server A 和 server B 使用
spring session
,公用同一个 redis 存储 session - server A 调用 server B 时,把 cookie 取出来然后传递给 server B
之前说过了 cookie 就是 key,server B 有了 cookie 肯定能拿到 session 的值了
这是 spring session 帮我们做的,虽然我没仔细看过源码,但是其步骤肯定如下:
- 检查请求头中是否有 cookie
- 检查是否有
SESSION=ABCDEFGHXXXX
的 cookie - 若有则根据
ABCDEFGHXXXX
去 redis 中查询数据,然后存放在 HttpSession 中
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于