SpringBoot项目连接Redis启动报错(Unable to validate object)
问题
某新项目(基于SpringBoot)在线上部署完成后启动失败,查看错误日志如下:
Error creating bean with name 'jedisPool'...
...
Caused by: redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool
...
Caused by: java.util.NoSuchElementException: Unable to validate object
...
分析&解决
项目使用了Redis,基于Jedis
封装了方便Redis操作的SpringBoot starter,里面在初始化配置时创建了ShardedJedisPool
。
项目使用了阿里云的应用配置管理(ACM),其中Redis连接相关参数配置在云上的yml文件中,配置了主机、端口、密码、数据库编号、超时参数等。
项目在测试环境启动正常,检查线上环境参数配置,通过阿里云的网页客户端连接Redis正常。
yml文件里Redis部分配置如下:
redis:
host: xxx.redis.rds.aliyuncs.com
port: 6379
password: xxx
database: 5
查看创建ShardedJedisPool
代码如下:
String password = redisProperties.getPassword();
password = !StringUtils.isEmpty(password) ? (":" + password + "@") : "";
String redisUri = "redis://" + password + host + ":" + port + "/" + database;
JedisShardInfo shard = new JedisShardInfo(redisUri);
注意到线上环境的Redis密码有特殊字符#
,查看new JedisShardInfo
,点进去看是通过URI.create(host)
来创建URI
对象,
而#
通过URLEncoder.encode()
编码为%23
,将redis.password
替换后重启项目,启动成功。
后续
项目后来引入了redisson
框架,使用分布式锁。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.5.0</version>
</dependency>
其中redisson配置如下:
redisson:
address: redis://${spring.redis.host}:${spring.redis.port}
password: ${spring.redis.password}
database: ${spring.redis.database}
构建RedissonClient
代码如下:
@Bean
@ConditionalOnProperty(
name = {"redisson.address"}
)
RedissonClient redissonSingle() {
Config config = new Config();
config.setLockWatchdogTimeout(this.redssionProperties.getLockWatchdogTimeout());
SingleServerConfig serverConfig = ((SingleServerConfig)config.useSingleServer().setDatabase(this.redssionProperties.getDatabase()).setAddress(this.redssionProperties.getAddress()).setTimeout(this.redssionProperties.getTimeout())).setConnectionPoolSize(this.redssionProperties.getConnectionPoolSize()).setConnectionMinimumIdleSize(this.redssionProperties.getConnectionMinimumIdleSize());
if (StringUtils.isNotBlank(this.redssionProperties.getPassword())) {
serverConfig.setPassword(this.redssionProperties.getPassword());
}
return Redisson.create(config);
}
项目启动报错,提示密码错误,注意到这里通过SingleServerConfig#setPassword
来设置密码,因此不需要使用转换后的密码,直接用原密码即可。
修改redisson配置如下:
redisson:
address: redis://${spring.redis.host}:${spring.redis.port}
password: xxx
database: ${spring.redis.database}
重新启动项目成功^_^!
参考
- 连接redis, 因为密码有特殊字符#, 导致无法正常连接 https://blog.csdn.net/cainiao1412/article/details/116269700
- java uri 空格_URI 中特殊字符处理 https://blog.csdn.net/weixin_35949153/article/details/114232736
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律