spring-session整合redis原理 排查失效原因
根据网上配置了一个springsession整合redis作为session后,发现session获取失败,redis里面是有值。登录模块设置进去也能获取的到,但是其他的服务就获取不到。记录一下,跟着源码探寻为何失败 auth服务的配置
- 引入依赖
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
- 编写配置
spring: cloud: nacos: discovery: server-addr: 192.168.0.94:8848 application: name: eshop-auth thymeleaf: cache: false session: store-type: redis redis: host: 192.168.0.94
- 使用注解 @EnableRedisHttpSession
- 扩大cookie的域名
@Configuration public class SessionConfig { @Bean public CookieSerializer cookieSerializer(){ DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); cookieSerializer.setDomainName("gulimall.com"); return cookieSerializer; } }
- 登录成功后设置session
@PostMapping("/login") public String login(UserLoginVo loginVo, HttpSession session) { session.setAttribute("user","123"); return "redirect:http://gulimall.com"; }
其他模块
探寻原理
- 从 @EnableRedisHttpSession 注解下手,可以看到它引入了另一个配置 RedissonHttpSessionConfiguration
- 而 RedissonHttpSessionConfiguration 又引入了一个 RedissonSessionRepository
- 并且 RedissonHttpSessionConfiguration 继承于 SpringHttpSessionConfiguration,这个类创建了一个filter
- 首先来分析 RedissonSessionRepository 就是封装了一些对session的增删改查的操作
- 再来看filter, 首先从刚才创建的 RedissonSessionRepository中获取放到内部
- 其中有一个方法
- 这个方法属于他的父类的抽象方法 OncePerRequestFilter
- dofilterinternal 方法内部把 request 和response 都包装了一遍传递给下一层
- 这时候我们来看 springmvc 的 session 是怎么获得的。 直接用 session 和 request的 getsession是同样一个东西
- 所以我们来看看包装的request里面的getsession是怎么实现的
- 由于我这次的问题是登录的session在主页找不到,所以一定是要有session 的,问题就出在 getRequestedSession 方法中 这个sessionRepository 就是一开始注解中引入的类
- RedisSessionRepository 中对于session的操作
至此我在跟踪源码的过程中发现,在获取 S session = SessionRepositoryFilter.this.sessionRepository.findById(sessionId); 这个方法中返回的数据是null 仔细排查发现实现类变成了RedissonSessionRepository 因为这个模块中有使用redisson作为分布式锁,所以在使用注解的时候 @EnableRedisHttpSession 自动提示成了 @EnableRedissonHttpSession 导致出现的bug。如果看不懂源码,这个问题可能需要非常久的时间才能排查出来.
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
示波器的使用及其原理