redis使用lettuce启动导致内存泄漏错误怎么解决

redis 使用 lettuce 出现

LEAK: hashedwheelTimer.release() was not called before it'
s garbage-collected. Enable advanced leak

内存泄漏。其实是内存不够大导致。

找到eclispe 中window->
preferences->
Java->
Installed JRE ,点击右侧的Edit 按钮,在编辑界面中的 “Default VM Arguments ”选项中,填入如下值即可。

Redis+Lettuce,如何解决内存泄漏错误

-Xms64m -Xmx128m

内存调的足够大可解决。

另一种方法无法解决。不知道是不是方法设置不对的问题

1、打开eclipse配置文件eclipse.ini,更改把-Xmx(其数值代表jvm可以使用的最大内存数)

2. 运行java程序时,选择run->
run configuration->
arguments,输入-Xms100M -Xmx800M(-Xms代表jvm启动时分配的内存大小,-Xmx代表可最大分配多少内存)。

补充:Redis连接池Lettuce踩坑记录

一、引言

最近,我们频繁地在不同的测试环境中部署项目,但在搭建和部署过程中遇到了很多Redis的问题。项目是基于SpringBoot2.1.12,SpringBoot2.1.X集成jar包Spring-data-redis-start 使用Lettuce作为Redis连接池。

SpringBoot1.x默认采用Jedis作为redis客户端连接池。

SpringBoot2.x,spring-data-redis 默认采用Lettuce作为redis客户端驱动连接池。

二、踩坑场景

运行环境Redis集群中某个master节点不稳定连接不上,导致SpringBoot应用连接Redis报错,报错连接timeout。

三、解决方案

重新编写 RedisConnectionFactory Bean,基于 Spring-data-redis。需要设置“取消校验集群节点的成员关系”:.validateClusterNodeMembership(false)。

1、redis配置spring:
redis:
cluster:
nodes:
- ${redis.host.cluster} #redis集群ip-port
password: ${redis.password}
timeout: 5000 #连接超时时间
lettuce:
pool:
max-active: 10 #连接池最大连接数
max-wait: -1 #连接池最大阻塞时间
max-idle: 5 #连接池中最大空闲连接
min-idle: 1 #连接池中最小空闲连接
redis:
cluster:
enabled: true 2、Config配置类@Data
@Component
@ConditionalOnProperty(name = "
redis.cluster.enabled"
, havingValue = "
true"
, matchIfMissing = false)
public class RedisConfig {
@Autowired
RedisProperties redisProperties;

// 在构建LettuceConnectionFactory时,如果不使用内置的destroyMethod,可能会导致Redis连接早于其它Bean被销毁
@Bean(destroyMethod = "
destroy"
)
public RedisConnectionFactory newLettuceConnectionFactory() {
// 配置用于开启自适应刷新和定时刷新。如自适应刷新不开启,Redis集群变更时将会导致连接异常
ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
.enablePeriodicRefresh(Duration.ofSeconds(60))// 开启周期刷新(默认60秒)
.enableAdaptiveRefreshTriggers(RefreshTrigger.ASK_REDIRECT,RefreshTrigger.UNKNOWN_NODE)// 开启自适应刷新
.build();

ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
.topologyRefreshOptions(clusterTopologyRefreshOptions)//拓扑刷新
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
.autoReconnect(true)
.socketOptions(SocketOptions.builder().keepAlive(true).build())
                 .validateClusterNodeMembership(false)// 取消校验集群节点的成员关系
.build();

LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.clientOptions(clusterClientOptions)
.readFrom(ReadFrom.SLAVE_PREFERRED)
.build();

return new LettuceConnectionFactory(getClusterConfiguration(), clientConfig);

}

private RedisClusterConfiguration getClusterConfiguration() {
RedisProperties.Cluster clusterProperties = redisProperties.getCluster();

RedisClusterConfiguration config = new RedisClusterConfiguration(clusterProperties.getNodes());

if (clusterProperties.getMaxRedirects() != null) {
config.setMaxRedirects(clusterProperties.getMaxRedirects());

}
if (redisProperties.getPassword() != null) {
config.setPassword(RedisPassword.of(redisProperties.getPassword()));

}
return config;

}
}

注意:

RedisClusterConfiguration getClusterConfiguration()需要设置Password,不然SpringBoot启动报认证错误:

“io.lettuce.core.RedisCommandExecutionException: NOAUTH Authentication required”

如下:

另外,lettuce-core jar包版本不能过低,避免部分配置项无法支持,以上配置为lettuce-core-5.18.RELEASE.jar。



Redis是一个非常流行的NoSQL数据存储工具,而Lettuce是Redis的Java客户端之一。然而,当使用Lettuce连接Redis时,会发现可能出现内存泄漏的问题。本文将介绍什么是内存泄漏,为什么会出现这个问题以及如何解决这个问题。
什么是内存泄漏?
内存泄漏是指由于疏忽或错误产生的内存占用无法释放的现象。在Java中,当一个对象不再被引用时,它应该被垃圾回收器回收,这样可以释放它所占用的内存。但是,如果程序员没有正确地维护对象的生命周期,例如忘记释放某些资源,那么这些对象就会被保留在内存中,导致内存占用越来越高,最终导致程序崩溃。
为什么会出现内存泄漏错误?
当使用Lettuce启动Redis时,我们可能会遇到内存泄漏。这通常是由于连接池中创建的线程没有正确地关闭导致的。如果我们不关闭连接池中创建的所有线程,那么这些线程会一直占用内存,并最终导致内存泄漏。
如何解决内存泄漏错误?
为了解决内存泄漏错误,我们需要正确地管理线程。我们可以使用try-with-resources语句,这样当离开try块时,自动关闭连接池中创建的所有线程。示例代码如下:
try (RedisClient client = RedisClient.create(\"redis://localhost\");
StatefulRedisConnection connection = client.connect()) {
// 待执行的代码
}
此外,我们还可以使用Redisson来解决内存泄漏问题。Redisson是一个基于Redis的分布式Java对象服务和锁服务。当使用Redisson时,它会自动关闭连接池中创建的所有线程,避免了手动关闭的问题。示例代码如下:
Config config = new Config();
config.useSingleServer().setAddress(\"redis://localhost:6379\");
RedissonClient client = Redisson.create(config);
RLock lock = client.getLock(\"anyLock\");
try {
lock.lock();
// 待执行的代码
} finally {
lock.unlock();
}
总结
内存泄漏是一个非常重要的问题,它会导致程序崩溃,并且很难定位。当使用Lettuce连接Redis时,我们需要注意线程的管理,避免发生内存泄漏。通过使用try-with-resources语句或Redisson,我们可以避免手动关闭连接池中创建的线程,并保证程序的稳定性和可靠性。