SpringBoot3.X:Unable to connect to Redis錯誤及解決方案
一.背景
最近在搭建一個新項目,本著有新用新的原則,項目選擇到了jdk17+SpringBoot3.4。
但是在測試Redis連接的時候卻遇到了以下問題:


redis連不上了。
于是我先去檢查了配置文件的連接信息,發(fā)現(xiàn)沒問題;再去檢查配置類:

也沒發(fā)現(xiàn)問題。
并且我去啟動了以前用SpringBoot2.X的老項目,發(fā)現(xiàn)同樣的配置下,以前的老項目就能成功連上Redis。那這下就大概可以確定原因了:SpringBoot3.4版本下,引用的spring-boot-starter-data-redis可能有點毛病。
二.發(fā)現(xiàn)問題
1.問題發(fā)現(xiàn)
既然可能是版本問題,那就只能去github上看看了

果然也有其它人遇到了相同的問題,不過還好這個問題已經(jīng)被解決了

翻譯一下就是:
Lettuce驅(qū)動程序版本在Spring Data和Spring Boot版本之間發(fā)生了變化,這些版本改變了握手行為。我建議您通過clientOptions.builder(). protocolversion (ProtocolVersion.RESP2).build()來配置LettuceClientConfiguration.clientOptions,來強制RESP2處理,這樣你就不會遇到HELLO錯誤,并且將使用AUTH命令來應用身份驗證。
看起來Lettuce客戶端已經(jīng)通過redis/ Lettuce #3035修復了6.5版本的問題。
在任何情況下,這都是驅(qū)動程序的問題。
據(jù)此可以得到兩種解決方案:
(1)手動配置LettuceClientConfiguration.clientOptions的protocolversion
(2)將Lettuce升級到6.5
2.問題驗證
我的“spring-boot-starter-data-redis”版本是跟著springboot版本走的,也就是3.4.0

接下來看一下“spring-boot-starter-data-redis”提供的lettuce依賴
可以看,到lettuce依賴版本默認是6.4.1,而不是已經(jīng)解決bug的6.5。接下來對程序debug驗證一下lettuce版本為6.4.1時,LettuceClientConfiguration.clientOptions的protocolversion

可以看到,Spring為我們自動配置的RedisConnectionFactory中,clientOptions的protocolVersion屬性為null,沒有被設置為RESP2。
三.解決方案
1.手動配置LettuceClientConfiguration.clientOptions的protocolversion
我們不使用Spring為我們自動配置的RedisConnectionFactory,而是自己配置一個LettuceConnectionFactory交給IOC容器管理。
在配置LettuceConnectionFactory時通過配置ClientOptions的protocolVersion為RESP2,來解決連接bug。
(1)配置代碼
自己配置LettuceConnectionFactory的話還需要引入外部連接池依賴
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
/**
* 配置線程池連接工廠LettuceConnectionFactory
* @return
*/
@Bean
public LettuceConnectionFactory lettuceConnectionFactory(){
// redis配置
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(host, port);
redisStandaloneConfiguration.setDatabase(dataBase);
redisStandaloneConfiguration.setPassword(password);
// 連接池配置
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMinIdle(minIdle);
genericObjectPoolConfig.setMaxIdle(maxIdle);
genericObjectPoolConfig.setMaxWait(Duration.ofDays(maxWait));
genericObjectPoolConfig.setMaxTotal(maxActive);
// ClientOptions配置
ClientOptions clientOptions = ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build();
// redis客戶端配置
LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
builder = LettucePoolingClientConfiguration
.builder()
.clientOptions(clientOptions)
.commandTimeout(Duration.ofMillis(timeOut));
builder.poolConfig(genericObjectPoolConfig);
LettuceClientConfiguration lettuceClientConfiguration = builder.build();
return new LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration);
}
(2)啟動驗證

可以看到此時注入進來的RedisConnectionFactory就是我們自己配置的LettuceConnectionFactory,其ClientOptions的protocolVersion屬性為RESP2。Redis可以被正常連接。
2.將Lettuce升級到6.5
這種方法就比較簡單粗暴了,既然“spring-boot-starter-data-redis”提供的lettuce依賴版本為6.4,那我們就不用它提供的了,自己引入版本為6.5的lettuce依賴。
(1)配置代碼
<!--redis-->
<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>
<!--lettuce-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>${lettuce.version}</version>
</dependency>
<!--外部連接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
其中l(wèi)ettuce.version是6.5.0.RELEASE。最下面的“commons-pool2”是如果要自己配置LettuceConnectionFactory才需要引入,也就是方案一要用到,這里沒有刪掉。
(2)啟動驗證

IOC容器中的Spring為我們自動配置的RedisConnectionFactory的clientOptions.protocolVersion仍然是null,但是此時Redis已經(jīng)可以正常連接上了,說明Lettuce 6.5.0已經(jīng)解決了認證連接bug。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Retrofit+Rxjava下載文件進度的實現(xiàn)
這篇文章主要介紹了Retrofit+Rxjava下載文件進度的實現(xiàn),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11
java中double強制轉(zhuǎn)換int引發(fā)的OOM問題記錄
這篇文章主要介紹了java中double強制轉(zhuǎn)換int引發(fā)的OOM問題記錄,本文給大家分享問題排查過程,感興趣的朋友跟隨小編一起看看吧2024-10-10
selenium+java+chrome環(huán)境搭建的方法步驟
這篇文章主要介紹了selenium+java+chrome環(huán)境搭建的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07
Java畢業(yè)設計實戰(zhàn)之藥店信息管理系統(tǒng)的實現(xiàn)
這是一個使用了java+SSM+JSP+layui+maven+mysql開發(fā)的藥店信息管理系統(tǒng),是一個畢業(yè)設計的實戰(zhàn)練習,具有藥店信息管理該有的所有功能,感興趣的朋友快來看看吧2022-01-01
java開發(fā)分布式服務框架Dubbo調(diào)用過程
這篇文章主要為大家介紹了java開發(fā)分布式服務框架Dubbo調(diào)用過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2021-11-11

