redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool

Exception in thread "main" redis.clients.jedis.exceptions.JedisException: Could not return the resource to the pool
    at redis.clients.util.Pool.returnBrokenResourceObject(Pool.java:103)
    at redis.clients.jedis.JedisSentinelPool.returnBrokenResource(JedisSentinelPool.java:234)
    at redis.clients.jedis.JedisSentinelPool.returnBrokenResource(JedisSentinelPool.java:17)
    at redis.clients.jedis.Jedis.close(Jedis.java:3407)
10:38:01.713 [main] ERROR com.kay.RedisSentinelTest - Could not get a resource from the pool
    at com.kay.RedisSentinelTest.main(RedisSentinelTest.java:53)
Caused by: java.lang.IllegalStateException: Invalidated object not currently part of this pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at redis.clients.util.Pool.getResource(Pool.java:53) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.JedisSentinelPool.getResource(JedisSentinelPool.java:209) ~[jedis-2.9.0.jar:na]
    at com.kay.RedisSentinelTest.main(RedisSentinelTest.java:38) ~[classes/:na]
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused: connect
    at redis.clients.jedis.Connection.connect(Connection.java:207) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:93) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1767) ~[jedis-2.9.0.jar:na]
    at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:106) ~[jedis-2.9.0.jar:na]
    at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868) ~[commons-pool2-2.4.2.jar:2.4.2]
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435) ~[commons-pool2-2.4.2.jar:2.4.2]
    at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363) ~[commons-pool2-2.4.2.jar:2.4.2]
    at redis.clients.util.Pool.getResource(Pool.java:49) ~[jedis-2.9.0.jar:na]
    ... 2 common frames omitted
Caused by: java.net.ConnectException: Connection refused: connect

测试 Redis Sentinel 时,发生Could not return the resource to the pool异常,一下是测试代码:

public class RedisSentinelTest {

    private static final Logger logger = LoggerFactory.getLogger(RedisSentinelTest.class);

    public static void main(String[] args) {
        String masterName = "mymaster";
        Set<String> sentinelSet = new HashSet<>();
        sentinelSet.add("172.16.1.114:26379");
        sentinelSet.add("172.16.1.114:26380");
        sentinelSet.add("172.16.1.114:26381");
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinelSet);
        int counter = 1;
        Jedis jedis = null;
        while (true) {
            counter++;
            try {
                jedis = jedisSentinelPool.getResource();
                int index = new Random().nextInt(1000000);
                String key = "k_" + index;
                String value = "v_" + index;
                jedis.set(key, value);

                if (counter % 200==0) {
                    logger.info("{} value is {}",key,jedis.get(key));
                }
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (Exception e) {
                logger.error(e.getMessage(),e);
            }finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
        }
    }
}

测试场景是,模拟主节点突然挂掉,redis sentinel会重新选举出一个从节点成为主节点,然后客户端重新连接上。

以上代码在主节点点断开后,main函数出现异常,导致无法重连。原因在于Could not return the resource to the pool, jedis 对象在主节点断开后,连接池已变为不可用,此时jedis对象仍然存活,继续执行 finally 内语句 jedis.close()放回连接池,所以导致异常。

解决方案,将 jedis置空的方法放到while循环里面,Jedis jedis=null,连接池不可用后jedis对象置空。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页