【java笔记】记一次线上redis之lettuce客户端创建异常问题
导读目前线上报错如下:ERROR [io.netty.util.ResourceLeakDetector 317] -LEAK: HashedWheelTimer.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for mo
·
导读
目前线上报错如下:
[Finalizer] WARN [io.lettuce.core.resource.DefaultClientResources 573] - io.lettuce.core.resource.DefaultClientResources was not shut down properly, shutdown() was not called before it's garbage-collected. Call shutdown() or shutdown(long,long,TimeUnit) []
ERROR [io.netty.util.ResourceLeakDetector 317] - LEAK: HashedWheelTimer.release() was not called before it's garbage-collected. See http://netty.io/wiki/reference-counted-objects.html for more information.
Recent access records:
Created at:
io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:284)
io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:217)
io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:196)
io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:178)
io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:162)
io.lettuce.core.resource.DefaultClientResources.<init>(DefaultClientResources.java:169)
io.lettuce.core.resource.DefaultClientResources$Builder.build(DefaultClientResources.java:532)
io.lettuce.core.resource.DefaultClientResources.create(DefaultClientResources.java:233)
io.lettuce.core.AbstractRedisClient.<init>(AbstractRedisClient.java:98)
io.lettuce.core.cluster.RedisClusterClient.<init>(RedisClusterClient.java:175)
io.lettuce.core.cluster.RedisClusterClient.create(RedisClusterClient.java:243)
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.lambda$createClient$5(LettuceConnectionFactory.java:958)
java.util.Optional.orElseGet(Optional.java:267)
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.createClient(LettuceConnectionFactory.java:958)
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.afterPropertiesSet(LettuceConnectionFactory.java:273)
大致的原因是:redis在重新创建lettuce客户端链接资源的时候,之前的客户端链接资源没有被回收。
解决方案
1、有问题代码
@Bean
public RedisConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig poolConfig) {
String nodesConfig = xxx;
String[] nodeHosts = nodesConfig.split(",");
RedisClusterConfiguration configuration = new RedisClusterConfiguration(Arrays.asList(nodeHosts));
/* ========= lettuce pool ========= */
LettucePoolingClientConfiguration lpc = LettucePoolingClientConfiguration.builder()
.commandTimeout(Duration.ofSeconds(10))
.poolConfig(poolConfig)
.build();
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, lpc);
// 连接池初始化
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
出现问题的代码主要在 connectionFactory.afterPropertiesSet(),初始化的过程中会创建客户端链接资源,在创建过程中,如果重新启动项目,没有回收资源从而导致。
2、修改后的代码
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(ClientResources.class)
public DefaultClientResources lettuceClientResources() {
return DefaultClientResources.create();
}
@Bean
public RedisConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig poolConfig,DefaultClientResources lettuceClientResources) {
String nodesConfig = xxx;
String[] nodeHosts = nodesConfig.split(",");
RedisClusterConfiguration configuration = new RedisClusterConfiguration(Arrays.asList(nodeHosts));
/* ========= lettuce pool ========= */
LettucePoolingClientConfiguration lpc = LettucePoolingClientConfiguration.builder()
.clientResources(lettuceClientResources)
.commandTimeout(Duration.ofSeconds(10))
.poolConfig(poolConfig)
.build();
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, lpc);
// 连接池初始化
connectionFactory.afterPropertiesSet();
return connectionFactory;
}
如上:增加了lettuceClientResources 客户端资源由Spring容器管理,并且在销毁的时候调用shutdown方法,然后将Spring管理的客户端资源bean传递给LettucePoolingClientConfiguration,并配置,完美解决问题
更多推荐
已为社区贡献1条内容
所有评论(0)