spring-session整合redis原理 排查失效原因

根据网上配置了一个springsession整合redis作为session后,发现session获取失败,redis里面是有值。登录模块设置进去也能获取的到,但是其他的服务就获取不到。记录一下,跟着源码探寻为何失败
auth服务的配置

  1. 引入依赖
        <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>
  1. 编写配置
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
  1. 使用注解 @EnableRedisHttpSession
  2. 扩大cookie的域名
@Configuration
public class SessionConfig {
    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setDomainName("gulimall.com");
        return cookieSerializer;
    }
}
  1. 登录成功后设置session
    @PostMapping("/login")
    public String login(UserLoginVo loginVo, HttpSession session) {
        session.setAttribute("user","123");
        return "redirect:http://gulimall.com";
    }

其他模块
在这里插入图片描述

探寻原理

  1. @EnableRedisHttpSession 注解下手,可以看到它引入了另一个配置 RedissonHttpSessionConfiguration
    在这里插入图片描述

  2. RedissonHttpSessionConfiguration 又引入了一个 RedissonSessionRepository在这里插入图片描述

  3. 并且 RedissonHttpSessionConfiguration 继承于 SpringHttpSessionConfiguration,这个类创建了一个filter
    在这里插入图片描述

  4. 首先来分析 RedissonSessionRepository
    就是封装了一些对session的增删改查的操作
    在这里插入图片描述

  5. 再来看filter, 首先从刚才创建的 RedissonSessionRepository中获取放到内部
    在这里插入图片描述

  6. 其中有一个方法
    在这里插入图片描述

  7. 这个方法属于他的父类的抽象方法 OncePerRequestFilter
    在这里插入图片描述

  8. dofilterinternal 方法内部把 request 和response 都包装了一遍传递给下一层
    在这里插入图片描述

  9. 这时候我们来看 springmvc 的 session 是怎么获得的。 直接用 session 和 request的 getsession是同样一个东西
    在这里插入图片描述

  10. 所以我们来看看包装的request里面的getsession是怎么实现的
    在这里插入图片描述

  11. 由于我这次的问题是登录的session在主页找不到,所以一定是要有session 的,问题就出在 getRequestedSession 方法中
    这个sessionRepository 就是一开始注解中引入的类
    在这里插入图片描述

  12. RedisSessionRepository 中对于session的操作
    在这里插入图片描述

至此我在跟踪源码的过程中发现,在获取
S session = SessionRepositoryFilter.this.sessionRepository.findById(sessionId);
这个方法中返回的数据是null
仔细排查发现实现类变成了RedissonSessionRepository

因为这个模块中有使用redisson作为分布式锁,所以在使用注解的时候 @EnableRedisHttpSession 自动提示成了 @EnableRedissonHttpSession 导致出现的bug。如果看不懂源码,这个问题可能需要非常久的时间才能排查出来.

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值