我们知道,对于一个单机系统来说,用户登陆成功后,一般情况下服务端会通过在httpRequest的session中存入登陆后的信息,客户端二次请求的时候,通过cookie对于的sessionId来获取验证用户的登陆状态。但是当业务量过大,需要拓展到多台机器来缓解单机瓶颈时,这种情况就不适用了。
如下所示,客户端第一次登陆请求进来,被nginx负载到服务器1,验证登陆通过后,登陆信息存放在服务器1上,当客户端第二次请求的时候,因此被分发到服务器2,而服务器2因为找不到服务器1的session信息,结果导致客户端又需要重新登陆一次。
为了解决这种情况,我们引入分布式会话,通过redis统一管理会话信息。
首先在pom.xml中引入redis和session的相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
在配置文件中添加redis配置信息
spring.redis.host=127.0.0.1
spring.redis.port=6379
这样springboot就会自动把session信息存入redis之中了,代码都不需要改动,是不是很简单。springbott默认的session过期时间是30分钟,如果需要修改,需新增自定义类
@Component
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
public class RedisSessionConfig {
}
这样基于cookie的分布式会话改造就完成了。
调用后发现redis中会存入以下的key
1) "spring:session:sessions:d228adc8-b16b-4486-b628-3df20ec6fb37"
2) "spring:session:sessions:expires:d228adc8-b16b-4486-b628-3df20ec6fb37"
3) "spring:session:expirations:1565977370000"
另外,公司有同事的处理方案是在nginx配置ip_hash,使指定IP固定分发到指定的服务端,这样也能保证session的稳定,但缺点是当其中某一个服务器挂了,那么这一IP段的用户都访问不了了,所以还是不太推荐的
- 本文链接: https://www.acgclub.xyz/archives/1573921171091
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!