最近开发反馈了一个问题,说系统使用了codis之后,发现当并发量上来之后,会抛出异常:could not get resource from pool,更底层的原因是:Timeout waiting for idle object,然后开始查问题。
1、可能是配置问题?
我们对jodis进行了一层浅封装,将配置进行独立,开放给开发人员的配置比较少,也就几个:
codis.pool.maxTotal=1000 //对象池最大数
codis.pool.maxIdle=1000 //idle对列最大数
codis.pool.minIdle=0 //idle队列最小数
codis.pool.maxWaitMillis=20000 //获取连接超时时间
没发现什么问题,因为其他系统也是就配置这几个参数,然后调整这些参数,没有任何改善,仍然会出现问题
2、代码分析
RoundRobinJedisPool代码中有如下代码:
public Jedis getResource() {
ImmutableList<PooledObject> pools = this.pools;
if (pools.isEmpty()) {
throw new JedisException("Proxy list empty");
}
for (;;) {
int current = nextIdx.get();//1.获取上次使用哪个proxy
int next = current >= pools.size() - 1 ? 0 : current + 1;//2.轮询到另外一个proxy
if (nextIdx.compareAndSet(current, next)) {// 3.设置本次使用的proxy,以供下次使用
return pools.get(next).pool.getResource();//获取该proxy的JedisPool并获取Jedis实例
}
}
}
(提出问题的同事发现的,感谢)for循环内部的代码不是原子的,尝试添加了同步块,突然发现,问题解决了,此问题不报了,到此,以为解决了