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}

重新啟動項目成功^_^!

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM