2017-04-19 70 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的加入也是模板。

不知道這是怎麼解決這個問題的,但對我來說保持最大空閒將會保留池中的一些空閒連接以供使用。

如果有人能解釋爲什麼這個配置解決了我的問題會很好。