【问题标题】:Jedis, Cannot get jedis connection: cannot get resource from pool绝地,无法获得绝地连接:无法从池中获取资源
【发布时间】:2017-09-15 11:47:05
【问题描述】:

我已经在几个线程中看到了答案,但对我来说没有用,因为我的问题偶尔会发生,如果有人有任何想法,请询问这个问题。

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

我有多个缓存保存在 redis 中,并且获取请求是从 redis 完成的。我正在使用 spring data redis APIs 来保存和获取数据。

所有保存和获取都可以正常工作,但偶尔会出现以下异常:

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;
 }

 }

有没有人遇到过这个问题或对此有任何想法,为什么会发生这种情况?

【问题讨论】:

  • 请发布完整的堆栈跟踪。
  • @mp911de:一旦我有数据就会提供。我们已经重新启动了我们的服务器,所以没有日志,并且由于这个问题偶尔会发生,我想我可能需要等待。
  • 这不是完整的堆栈跟踪。连接失败的原因通常在最后(JedisConnectionException 的原因)。
  • 我无法在我的应用程序中打印堆栈跟踪。所以我试图从 Throwable.getStackTrace() 捕获它并记录它。这给了我上面的堆栈跟踪。 stacktrace 中还有更多内容,但这是我没有包含的应用程序方法。这就是我所拥有的。

标签: spring redis jedis spring-data-redis


【解决方案1】:

我们在使用 RxJava 时遇到了同样的问题,应用程序运行良好,但一段时间后,无法再从池中获取任何连接。经过几天的调试,我们终于找出了问题的原因:

redisTemplate.setEnableTransactionSupport(true)

不知何故导致 spring-data-redis 不释放连接。我们需要对 MULTI / EXEC 的事务支持,但最终更改了实现以摆脱这个问题。

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

【讨论】:

  • 我遇到了同样的问题,但就我而言,我使用的是 RxJava。 spring-data-redis 的事务支持类似乎使用了 ThreadLocal 变量,这在我的情况下不起作用。你在使用任何异步框架吗?
  • @Thomas 在我们的例子中也是 RxJava,我更新了我的答案。
  • @Thomas 刚刚看到你的回答,我已经有一段时间发布了这个问题。我确实通过玩配置解决了这个问题,添加到配置下面,这解决了我的问题:poolConfig.setMaxIdle(30); poolConfig.setMinIdle(10);
【解决方案2】:

我从 redis.template 转移到了普通的 jedis。 为池添加了以下配置(也可以在redis模板中添加),现在看不到任何异常:

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

redis 模板:

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

同样的配置也可以添加到redis模板中。

【讨论】:

  • 嗯,它似乎也对我有用,但我不知道为什么。你介意详细说明一下吗?基本上我的问题是如果我的应用程序将用完空闲连接怎么办。 (current_connections > max_idle)
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 2012-10-14
  • 2014-03-30
  • 2015-03-02
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多