• 首页 > 
  • 使用Jedis连接池模式遇到无法获取连接池的错误

使用Jedis连接池模式遇到无法获取连接池的错误

KB: 53108

 · 

更新时间:2020-04-07 16:44

概述

使用Jedis连接池模式容易遇到无法获取连接池的错误如下。

redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

详细信息

可以根据以下几种方法进行分类排查。

检查网络

  1. 通过telnet命令进行简单测试。
  2. 连接之后,执行下列命令,查看是否返回“+OK\r\n”,如果返回则继续检查。
    auth [$Password]
    说明:[$Password]为密码。
  3. ping请求或者读写请求是否正常返回,操作多次排查网络问题影响。

检查JedisPool连接数设置

  1. JedisPool使用的时候需要进行连接池的设置,用户在超过MaxTotal连接数的时候也会出现获取不到连接池的情况,这个时候可以在访问客户端上执行下列命令,查看链接的客户端连接数目。
    netstat -an | grep 6379 | grep EST | wc -l
  2. 并且比较这个数目和JedisPool配置的MaxTotal值,如果没有明显超过或者接近就可以排除JedisPool连接池配置的影响。

检查JedisPool连接池代码

对于JedisPool连接池的操作,每次getResource之后需要调用returnResource或者close进行归还,可以查看代码是否是正确使用,代码示例如下。

JedisPoolConfig config = new JedisPoolConfig();
//最大空闲连接数,应用自己评估,不要超过ApsaraDB for Redis每个实例最大的连接数
config.setMaxIdle(200);
//最大连接数,应用自己评估,不要超过ApsaraDB for Redis每个实例最大的连接数
config.setMaxTotal(300);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
String host = "*.aliyuncs.com";
String password = "密码";
JedisPool pool = new JedisPool(config, host, 6379, 3000, password);
Jedis jedis = null;
try {
    jedis = pool.getResource();
    /// ... do stuff here ... for example
    jedis.set("foo", "bar");
    String foobar = jedis.get("foo");
    jedis.zadd("sose", 0, "car");
    jedis.zadd("sose", 0, "bike");
    Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
    if (jedis != null) {
        jedis.close();
    }
}
/// ... when closing your application:
pool.destroy();

检查是否发生nf_conntrack丢包

通过dmesg检查客户端是否有异常。如果发生nf_conntract丢包可以修改设置,参考sysctl -w net.netfilter.nf_conntrack_max=120000命令。

nf_conntrack: table full, dropping packet

检查是否TIME_WAIT问题

  1. 通过ss -s命令查看time wait链接是否过多,结果如下。
  2. 如果TIME_WAIT过多,请依次执行下列命令,修改内核参数。
    sysctl -w net.ipv4.tcp_max_tw_buckets=180000
    sysctl -w net.ipv4.tcp_tw_recycle=1

检查是否DNS解析问题

/etc/hosts文件直接绑定host地址,绑定完成之后查看问题是否还存在,如果还存在则不是DNS解析问题。

192.XXX.XXX.1  *.redis.rds.aliyuncs.com

其他

如果按照上面排查之后还有问题,可以通过抓包并将报错时间点、报错信息、抓包文件通过工单提交给阿里云工程师分析。抓包命令如下。
sudo tcpdump -i eth0 tcp and port 6379 -n -nn -s 74 -w redis.cap

适用于

  • 云数据库 Redis