起因
原先使用的是 spring-data-redis,底层使用 Client 是 lettuce,当引入 redisson-spring-boot-starter 依赖之后,出现使用 RedisTemplate 抛出的 StackOverflowError 异常,如下图所示:
尝试 debug 发现当调用 RedisTemplate 的 Redis Command 方法时(leftpop),底层使用 connection 是 RedissonConnection:
这里没有深究为什么使用 RedissonConnection 会出现 StackOverflowError 根本原因,但从表面上可以推断,替换成原始的 LettuceConnection 应该能恢复正常。
排查 LettuceConnectionConfiguration 自动配置类发现,当 Spring 容器中已经存在 RedisConnectionFactory Bena 时,将不会创建 LettuceConnectionFactory Bean:
而使用 redisson-spring-boot-starter ,会在 RedissonAutoConfiguration 配置类中自动注册 RedissonConnectionFactory 和 RedisTemplate Bean:
解决
不使用 redisson-spring-boot-starter 自动装配,而是自己来注册 RedissonClient:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.17.5</version>
</dependency>
配置类:
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress(String.format("redis://%s:%d", redisHost, redisPort));
return Redisson.create(config);
}
}
这样在使用 RedisTemplate 时,底层使用 Connection 实现则是 LettuceConnection 了: