记一次jedis错误Could not get a resource from the pool

特别提示:每个人导致的该报错的原因不一样。

已经做过的排查:

1.排查了地址池初始化问题

2.排查了所有调用地方是否都关闭了

3.排查了配置参数

以上步骤排查完,程序还是会报错。

通过 JedisPool 的 getNumActive 方法,知道连接数会一直增加

通过在redis控制台输入client list,获得以下信息:

每个字段含义如下:
addr:客户端的地址和端口 
fd:套接字所使用的文件描述符 
idle:以秒计算的空闲时长 
flags:客户端 flag 
db:该客户端正在使用的数据库 ID 
sub:已订阅频道的数量 
psub:已订阅模式的数量 
multi:在事务中被执行的命令数量 
qbuf:查询缓冲区的长度(字节为单位, 0 表示没有分配查询缓冲区) 
qbuf-free:查询缓冲区剩余空间的长度(字节为单位, 0 表示没有剩余空间) 
obl:输出缓冲区的长度(字节为单位, 0 表示没有分配输出缓冲区) 
oll:输出列表包含的对象数量(当输出缓冲区没有剩余空间时,命令回复会以字符串对象的形式被入队到这个队列里) 
omem:输出缓冲区和输出列表占用的内存总量 
events:文件描述符事件 
cmd:最近一次执行的命令

通过上图,得到以下信息:

1. idle表示空闲时长,确定未释放连接的缘故,导致连接池无空闲连接。

2.发现都是写入操作

去查找封装的jedis操作类,发现调用方基本都是调用该方法,有设置过期时间。

记一次jedis错误Could not get a resource from the pool_第1张图片

在set方法中添加日志,查看是写入了那些key和second值。

敲黑板:缓存失效时间小于0时,抛出异常。

到这里的时候,在日志文件中也发现了一条 ERR invalid expire time in setex 错误日志。

确定自己的怀疑,可能是某个地方调用时,会传入负数,排查到后加上非负数处理,至此问题解决。

啰嗦几句:是多线程环境,日志中只有Could not get a resource from the pool错误, ERR invalid expire time in setex 错误是唯一一条,不眼尖还发现不了。写入异常可能在深层次的代码中被处理了,没有被抛出来。

 

 

你可能感兴趣的:(Java)