【bug排查记录】由Redission配置引发的Satoken血案

发布于:2025-05-27 ⋅ 阅读:(54) ⋅ 点赞:(0)

背景

在今天服务更改服务配置的redis的database后,本地测试通过,发布到线上。出现所有用户登录状态失效,并且重新登录后也是失效的问题,由于鉴权登录框架使用的是satoken,线上database配置的是1,然后去redis中查看,确实是存在对应登录的token的,然后实在没办法,就在本地复现一下,本地使用的database是0,这时候用户服务 登录后正常,其余服务鉴权也正常,换成1后,就出现了问题,这时候去看redis 其中是存在用户token信息的,然后逐步去排查,到satoken的底层获取token时,发现了问题,redisclient中的 database是0,但是配置的是1,同时通过配置注入拿到的也是1
在这里插入图片描述
在这里插入图片描述

然后发现,Redis的connection是redission的,这时候去看redission的配置文件,发现指定的是0,到这就解决了,是redission配置的redis链接
从你提供的两张截图分析:

  • 第一张截图里,SingleServerConfigdatabase0
  • 第二张截图里,你的配置类(比如叫 RedisCacheConfig)中 redisDatabase = 1,配置正确传递到了你的配置类中
  • 同时第二张截图中的 redisConnectionFactoryRedisConnectionFactory 的实例,但数据库还是0(从第一张截图推断,这个底层配置数据库是0)

结合这两张截图和现象,问题核心是:

配置项 spring.data.redis.database=1 被正确加载到了你的配置类里,但是底层真正创建 Redis 连接(SingleServerConfig)时,数据库索引依然是0,说明配置没有传递到底层客户端的连接配置(比如 Lettuce 或 Redisson)中。


具体原因和排查方向

1. Redis Client 是什么?

你截图展示了 SingleServerConfig,这是 Redisson 的配置类,不是 Spring Data Redis 默认的 Lettuce 或 Jedis 客户端。

  • Redisson 自带了自己的连接配置(SingleServerConfig),它不会自动读取 Spring Boot 的 spring.data.redis.* 配置。
  • 你配置文件里设置的 spring.data.redis.database 是给 Spring Data Redis Lettuce/Jedis 客户端使用的,但你项目中可能还用了 Redisson,且 Redisson 的配置不是从 Spring 配置文件读取,而是单独配置的。
2. 你的 RedisCacheConfig 配置了 redisDatabase=1,但传给 Redisson 的 SingleServerConfig 里并没有正确设置数据库索引。

解决方案

你需要确认并修改 Redisson 的配置,显式地指定数据库索引为 1。

示例(基于 Redisson 的Java配置):

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Value("${spring.data.redis.host}")
    private String redisHost;

    @Value("${spring.data.redis.port}")
    private int redisPort;

    @Value("${spring.data.redis.password}")
    private String redisPassword;

    @Value("${spring.data.redis.database}")
    private int redisDatabase;

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() {
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer();
        serverConfig.setAddress("redis://" + redisHost + ":" + redisPort);
        serverConfig.setPassword(redisPassword);
        serverConfig.setDatabase(redisDatabase);  // **关键,设置数据库为1**
        return Redisson.create(config);
    }
}

总结

  • Spring Boot 的spring.data.redis.database配置后面只对Spring Data Redis默认客户端生效(Lettuce/Jedis)
  • Redisson使用单独的配置对象(SingleServerConfig),需要你手动把数据库索引传进去
  • 你当前的Redisson配置缺少 setDatabase(1),因此用的是默认的数据库0

你只要在你的 Redisson 配置类里,给 SingleServerConfig 显式调用 setDatabase(redisDatabase),这样底层 Redis 连接才会连接到数据库1,而不是默认的0。