Spring Boot 3.X:Unable to connect to Redis错误记录

一.背景

最近在搭建一个新项目,本着有新用新的原则,项目选择到了jdk17+SpringBoot3.4。但是在测试Redis连接的时候却遇到了以下问题:

redis连不上了。于是我先去检查了配置文件的连接信息,发现没问题;再去检查配置类:

也没发现问题。并且我去启动了以前用SpringBoot2.X的老项目,发现同样的配置下,以前的老项目就能成功连上Redis。那这下就大概可以确定原因了:SpringBoot3.4版本下,引用的spring-boot-starter-data-redis可能有点毛病。

二.发现问题

1.问题发现

既然可能是版本问题,那就只能去github上看看了

果然也有其它人遇到了相同的问题,不过还好这个问题已经被解决了

翻译一下就是:

Lettuce驱动程序版本在Spring Data和Spring Boot版本之间发生了变化,这些版本改变了握手行为。我建议您通过clientOptions.builder(). protocolversion (ProtocolVersion.RESP2).build()来配置LettuceClientConfiguration.clientOptions,来强制RESP2处理,这样你就不会遇到HELLO错误,并且将使用AUTH命令来应用身份验证。

看起来Lettuce客户端已经通过redis/ Lettuce #3035修复了6.5版本的问题。

在任何情况下,这都是驱动程序的问题。

据此可以得到两种解决方案:

(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,而不是已经解决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的话还需要引入外部连接池依赖

XML 复制代码
        <dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
java 复制代码
    /**
     * 配置线程池连接工厂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)配置代码

XML 复制代码
        <!--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>

其中lettuce.version是6.5.0.RELEASE。最下面的"commons-pool2"是如果要自己配置LettuceConnectionFactory才需要引入,也就是方案一要用到,这里没有删掉。

(2)启动验证

IOC容器中的Spring为我们自动配置的RedisConnectionFactory的clientOptions.protocolVersion仍然是null,但是此时Redis已经可以正常连接上了,说明Lettuce 6.5.0已经解决了认证连接bug。

相关推荐
涉密IT资质笔记3 分钟前
涉密资质投入产出分析模型:时间成本、四块成本构成与 ROI 决策框架
java·开发语言·算法
木井巳5 分钟前
【BFS 解决拓扑排序】火星词典
java·算法·leetcode·广度优先·宽度优先·图搜索算法
霸道流氓气质6 分钟前
Java调用StableDiffusion/ComfyUI图像生成:DAG工作流编排、WebSocket实时进度与Flux模型集成的生产级实战
java·websocket·stable diffusion
北风toto16 分钟前
KMP 算法详解:从暴力匹配到 O(n+m) 的字符串搜索
java·开发语言·算法
william_yangshun17 分钟前
WordCraft 观察:纯 Rust 重写文字处理器,把文档变成可编程对象
开发语言·后端·rust·文档自动化
weixin1997010801617 分钟前
《京东JOS API:落地方案、接口边界与业务踩坑 —— 联盟免费 vs 商家按量的双轨制》(附python源码)
java·网络·python
衡石科技20 分钟前
从语义准备到模型验收:HENGSHI SENSE Data Agent 的 RAG 与部署工程实践
java·大数据·人工智能·数据分析·rag
G018_star sky♬21 分钟前
java学习日记-多态与好玩的写法
java
撸串-研究生23 分钟前
面向景区的综合服务管理平台设计——以稻城亚丁景区为例【附源码】
java·开发语言·vue.js·前后端分离·稻城亚丁景区
IT_陈寒28 分钟前
SpringBoot开发实战:从入门到精通
前端·人工智能·后端