2017-04-19 289 views
4

我已经在几个线程中看到了答案,但对我而言并没有解决,因为偶尔会出现问题,如果有任何问题,请询问此问题。Jedis,无法获得jedis连接:无法从池中获取资源

我使用jedis 2.8.0版本,Spring Data redis 1.7.5版本。和我们的缓存应用程序的Redis服务器版本2.8.4。

我有多个缓存保存在redis中,并从redis获取请求。我正在使用spring数据redis API来保存和获取数据。

全部保存,并获得优良工程,但得到的异常下面偶尔:

Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool | org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the poolorg.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool 
org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:198) 
org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:345) 
org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:129) 
org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:92) 
org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:79) 
org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) 
org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:166) 
org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:88) 
org.springframework.data.redis.core.DefaultHashOperations.get(DefaultHashOperations.java:49) 

我redis的配置类:

@Configuration 
public class RedisConfiguration { 

@Value("${redisCentralCachingURL}") 
private String redisHost; 

@Value("${redisCentralCachingPort}") 
private int redisPort; 

@Bean 
public StringRedisSerializer stringRedisSerializer() { 
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); 
    return stringRedisSerializer; 
} 

@Bean 
JedisConnectionFactory jedisConnectionFactory() { 
    JedisConnectionFactory factory = new JedisConnectionFactory(); 
    factory.setHostName(redisHost); 
    factory.setPort(redisPort); 
    factory.setUsePool(true); 
    return factory; 
} 

@Bean 
public RedisTemplate<String, Object> redisTemplate() { 
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); 
    redisTemplate.setConnectionFactory(jedisConnectionFactory()); 
    redisTemplate.setExposeConnection(true); 
    // No serializer required all serialization done during impl 
    redisTemplate.setKeySerializer(stringRedisSerializer()); 
    //`redisTemplate.setHashKeySerializer(stringRedisSerializer()); 
    redisTemplate.setHashValueSerializer(new GenericSnappyRedisSerializer()); 
    redisTemplate.afterPropertiesSet(); 
    return redisTemplate; 
} 

@Bean 
public RedisCacheManager cacheManager() { 
    RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate()); 
    redisCacheManager.setTransactionAware(true); 
    redisCacheManager.setLoadRemoteCachesOnStartup(true); 
    redisCacheManager.setUsePrefix(true); 
    return redisCacheManager; 
} 

} 

这儿还有没有人遇到这个问题,或者对此有什么想法,为什么会这发生了吗?

+0

请发布完整的堆栈跟踪。 – mp911de

+0

@ mp911de:将提供一次我有数据。我们重新启动了我们的服务器,因此没有日志,并且由于偶尔会发生此问题,所以我猜可能需要等待。 –

+0

这不是完整的堆栈跟踪。连接失败的原因通常在最后(导致JedisConnectionException')。 – mp911de

回答

1

我们遇到了与RxJava相同的问题,该应用程序运行良好,但过了一段时间后,不再有任何连接可以从池中获取。经过调试的日子里,我们终于找到了问题的根源:

redisTemplate.setEnableTransactionSupport(true) 

某种程度上造成弹簧数据redis的不释放连接。我们需要MULTI/EXEC的事务支持,但最终改变了实现来摆脱这个问题。

我们仍然不知道这是错误还是错误的用法。

+0

我有同样的问题,但在我的情况下,我使用RxJava。 spring-data-redis的事务支持类似乎使用了ThreadLocal变量,这对我来说不起作用。你在使用任何异步框架吗? – Thomas

+0

@Thomas在我们的例子中,它也是RxJava,我更新了我的答案。 – woezelmann

+0

@Thomas刚才看到你的回答,有一段​​时间我发布了这个问题。我确实通过玩配置来解决这个问题,在config下面添加,这解决了我的问题: poolConfig.setMaxIdle(30); poolConfig.setMinIdle(10); –

0

我从redis.template移到plain jedis。 增加以下配置池(可在模板的Redis也加入),并没有看到现在任何异常:

jedisPoolConfig.setMaxIdle(30); 
jedisPoolConfig.setMinIdle(10); 

对Redis的模板:

jedisConnectionFactory.getPoolConfig().setMaxIdle(30); 
jedisConnectionFactory.getPoolConfig()poolConfig.setMinIdle(10); 

与上述相同的配置可以在Redis的加入也是模板。

不知道这是怎么解决这个问题的,但对我来说保持最大空闲将会保留池中的一些空闲连接以供使用。

如果有人能解释为什么这个配置解决了我的问题会很好。