前言
在单体项目中,由于客户的所有请求都是由一台服务器来处理,会话通过 SessionId 保存是没有问题的。后期随着业务的扩展,单体应用无法承受过多的用户请求,一旦项目变为分布式,就会出现 SessionId 共享问题。
举个栗子:现在有两台服务器同时运行,分别是 Server A 和 Server B,通过 Nginx 配置负载均衡后,客户端的请求会被随机分配到两台服务器上进行处理。
假设客户现在有第一次请求(登录请求)被分配到 Server A 进行处理,Server A 接受到请求之后会生成 SessionId 并且保存到内存当中,然后返回给用户(浏览器),浏览器会把 SessionId 保存到 Cookie 中,第一次请求完成。
若之后每一次请求还是由 Server A 来处理当然一切正常,但是一旦出现意外(比如 Server A 宕机)或者 Nginx 采用了轮询、weight 方式的负载均衡,请求被分配到 Server B进行处理。该情况下由于 Server B 拿到客户请求的 SessionId 是由 Server A 生成的,便会出现 SessionId 不一致问题 !
于是用户会发现,本来逛网站还好好的,突然就跳到登录页需要重新登录了???
这种情况下用户的体验自然不会太好,那么遇到此类问题我们应怎么去解决呢?
既然问题的根源出在 SessionId 无法共享上面,那么是不是让 SessionId 可以在多台服务器之间共享就可以了?
解决方案
是这样的,所以我们可以将 SessionId 保存到 Redis 中,验证时不再从当前服务器获取 SessionId 而改从 Redis 中获取!
具体实现步骤如下:
- 前端登录页面提交用户名密码
- 登录成功后根据一定规则(比如使用 UUID)生成 token(其相当于原来的 Sessionid)
- 将用户信息保存到 Redis(key 就是 token,value 就是 userId)
- 设置 key 的过期时间
- 拦截器拦截请求校验 SessionId
文章信息
| 时间 | 说明 |
|---|---|
| 2019-04-20 | 初稿 |