Redission与Satoken整合时Redis数据库配置的那些坑附完整解决方案当你在Spring Boot项目中同时使用Redission和Satoken时Redis数据库配置可能会成为一个隐藏的定时炸弹。我就曾踩过这样的坑——明明所有配置看起来都正确线上环境却突然出现所有用户登录状态失效的诡异现象。经过一番排查发现问题竟然出在两个框架对Redis数据库配置的读取方式差异上。1. 问题现象与初步排查那天早上我们刚把修改了Redis database配置的服务部署到线上噩梦就开始了。用户反馈登录后系统频繁跳转回登录页面查看Redis数据库发现token确实存在但系统就是无法识别。以下是当时观察到的具体现象本地环境database0一切正常线上环境database1登录状态无法保持Redis中确实存在token数据服务重启后问题依旧使用以下命令检查Redis数据存储情况时确认数据确实写入了database 1redis-cli -n 1 keys *2. 深度问题分析2.1 配置冲突的根源问题的核心在于Spring Boot项目中存在两套Redis客户端配置Spring Data Redis通过application.properties配置spring.data.redis.database1 spring.data.redis.host127.0.0.1 spring.data.redis.port6379Redission客户端需要单独配置Bean public RedissonClient redissonClient() { Config config new Config(); config.useSingleServer() .setAddress(redis://localhost:6379) // 缺少database配置默认使用0 .setPassword(password); return Redisson.create(config); }2.2 Satoken的工作机制Satoken默认使用Spring Data Redis的RedisTemplate进行操作但当项目中同时存在Redission时可能会发生以下情况组件配置来源默认database影响范围Spring Data Redisapplication.properties按配置Satoken鉴权Redission独立Java配置0如未显式设置分布式锁等3. 完整解决方案3.1 统一Redission配置确保Redission使用与Satoken相同的database配置Configuration public class RedissonConfig { Value(${spring.data.redis.host}) private String host; Value(${spring.data.redis.port}) private String port; Value(${spring.data.redis.database}) private int database; Value(${spring.data.redis.password}) private String password; Bean(destroyMethod shutdown) public RedissonClient redissonClient() { Config config new Config(); config.useSingleServer() .setAddress(redis:// host : port) .setPassword(password) .setDatabase(database); // 关键配置 return Redisson.create(config); } }3.2 验证配置生效创建测试端点验证Redis连接使用的databaseRestController public class RedisCheckController { Autowired private RedissonClient redissonClient; GetMapping(/check-redis) public String checkRedisConfig() { return 当前Redission使用的database: redissonClient.getConfig().useSingleServer().getDatabase(); } }4. 进阶配置建议4.1 多数据源场景处理当项目需要连接多个Redis实例时建议采用以下结构src/main/resources ├── application.yml └── redis ├── redisson-config.yml └── satoken-redis-config.yml对应的Java配置Configuration ConfigurationProperties(prefix satoken.redis) public class SaTokenRedisConfig { private int database; private String host; private int port; // getters setters Bean(name saTokenRedisTemplate) public RedisTemplateString, Object saTokenRedisTemplate() { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory()); return template; } Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config new RedisStandaloneConfiguration(); config.setHostName(host); config.setPort(port); config.setDatabase(database); return new LettuceConnectionFactory(config); } }4.2 配置检查清单部署前务必确认以下事项[ ] Redission配置中的database与Satoken一致[ ] 测试环境与生产环境配置同步[ ] Redis服务端已创建目标database[ ] 防火墙规则允许访问指定端口5. 常见问题排查指南遇到问题时可以按照以下步骤排查确认Redis连接信息// 获取Redission当前配置 redissonClient.getConfig().useSingleServer().getAddress(); redissonClient.getConfig().useSingleServer().getDatabase();检查Satoken存储情况// 获取当前会话token String tokenValue SaHolder.getStorage().getSaToken(); // 检查Redis中是否存在 redisTemplate.opsForValue().get(tokenValue);网络连通性测试telnet redis-host 6379权限验证redis-cli -h host -p port -a password6. 性能优化建议在解决基础配置问题后还可以考虑以下优化措施连接池配置config.useSingleServer() .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(24) .setIdleConnectionTimeout(10000);序列化优化Bean public RedisTemplateString, Object redisTemplate() { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; }监控集成!-- pom.xml -- dependency groupIdorg.redisson/groupId artifactIdredisson-spring-boot-starter/artifactId version3.17.0/version /dependency在实际项目中我们最终采用了配置中心动态刷新的方案使得Redis配置可以在不重启服务的情况下进行更新。这个方案虽然增加了初期实现的复杂度但为后续的运维工作带来了极大便利。
Redission与Satoken整合时Redis数据库配置的那些坑(附完整解决方案)
Redission与Satoken整合时Redis数据库配置的那些坑附完整解决方案当你在Spring Boot项目中同时使用Redission和Satoken时Redis数据库配置可能会成为一个隐藏的定时炸弹。我就曾踩过这样的坑——明明所有配置看起来都正确线上环境却突然出现所有用户登录状态失效的诡异现象。经过一番排查发现问题竟然出在两个框架对Redis数据库配置的读取方式差异上。1. 问题现象与初步排查那天早上我们刚把修改了Redis database配置的服务部署到线上噩梦就开始了。用户反馈登录后系统频繁跳转回登录页面查看Redis数据库发现token确实存在但系统就是无法识别。以下是当时观察到的具体现象本地环境database0一切正常线上环境database1登录状态无法保持Redis中确实存在token数据服务重启后问题依旧使用以下命令检查Redis数据存储情况时确认数据确实写入了database 1redis-cli -n 1 keys *2. 深度问题分析2.1 配置冲突的根源问题的核心在于Spring Boot项目中存在两套Redis客户端配置Spring Data Redis通过application.properties配置spring.data.redis.database1 spring.data.redis.host127.0.0.1 spring.data.redis.port6379Redission客户端需要单独配置Bean public RedissonClient redissonClient() { Config config new Config(); config.useSingleServer() .setAddress(redis://localhost:6379) // 缺少database配置默认使用0 .setPassword(password); return Redisson.create(config); }2.2 Satoken的工作机制Satoken默认使用Spring Data Redis的RedisTemplate进行操作但当项目中同时存在Redission时可能会发生以下情况组件配置来源默认database影响范围Spring Data Redisapplication.properties按配置Satoken鉴权Redission独立Java配置0如未显式设置分布式锁等3. 完整解决方案3.1 统一Redission配置确保Redission使用与Satoken相同的database配置Configuration public class RedissonConfig { Value(${spring.data.redis.host}) private String host; Value(${spring.data.redis.port}) private String port; Value(${spring.data.redis.database}) private int database; Value(${spring.data.redis.password}) private String password; Bean(destroyMethod shutdown) public RedissonClient redissonClient() { Config config new Config(); config.useSingleServer() .setAddress(redis:// host : port) .setPassword(password) .setDatabase(database); // 关键配置 return Redisson.create(config); } }3.2 验证配置生效创建测试端点验证Redis连接使用的databaseRestController public class RedisCheckController { Autowired private RedissonClient redissonClient; GetMapping(/check-redis) public String checkRedisConfig() { return 当前Redission使用的database: redissonClient.getConfig().useSingleServer().getDatabase(); } }4. 进阶配置建议4.1 多数据源场景处理当项目需要连接多个Redis实例时建议采用以下结构src/main/resources ├── application.yml └── redis ├── redisson-config.yml └── satoken-redis-config.yml对应的Java配置Configuration ConfigurationProperties(prefix satoken.redis) public class SaTokenRedisConfig { private int database; private String host; private int port; // getters setters Bean(name saTokenRedisTemplate) public RedisTemplateString, Object saTokenRedisTemplate() { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory()); return template; } Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration config new RedisStandaloneConfiguration(); config.setHostName(host); config.setPort(port); config.setDatabase(database); return new LettuceConnectionFactory(config); } }4.2 配置检查清单部署前务必确认以下事项[ ] Redission配置中的database与Satoken一致[ ] 测试环境与生产环境配置同步[ ] Redis服务端已创建目标database[ ] 防火墙规则允许访问指定端口5. 常见问题排查指南遇到问题时可以按照以下步骤排查确认Redis连接信息// 获取Redission当前配置 redissonClient.getConfig().useSingleServer().getAddress(); redissonClient.getConfig().useSingleServer().getDatabase();检查Satoken存储情况// 获取当前会话token String tokenValue SaHolder.getStorage().getSaToken(); // 检查Redis中是否存在 redisTemplate.opsForValue().get(tokenValue);网络连通性测试telnet redis-host 6379权限验证redis-cli -h host -p port -a password6. 性能优化建议在解决基础配置问题后还可以考虑以下优化措施连接池配置config.useSingleServer() .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(24) .setIdleConnectionTimeout(10000);序列化优化Bean public RedisTemplateString, Object redisTemplate() { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory()); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; }监控集成!-- pom.xml -- dependency groupIdorg.redisson/groupId artifactIdredisson-spring-boot-starter/artifactId version3.17.0/version /dependency在实际项目中我们最终采用了配置中心动态刷新的方案使得Redis配置可以在不重启服务的情况下进行更新。这个方案虽然增加了初期实现的复杂度但为后续的运维工作带来了极大便利。