如何重现could not return the resource to the pool
发布网友
发布时间:2022-05-29 04:11
我来回答
共2个回答
热心网友
时间:2024-08-18 22:51
1,JedisPool的使用
<!-- 连接池的配置信息 -->
<bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 说明一个pool可以有多少个Jedis实例 -->
<property name="maxActive" value="10" />
<!-- 最大Idle-->
<property name="maxIdle" value="5" />
<!-- 最小Idle -->
<property name="minIdle" value="1" />
<!-- 获得一个jedis实例的时候是否检查连接可用性(ping()) -->
<property name="testOnBorrow" value="true" />
<!-- return 一个jedis实例给pool时,是否检查连接可用性(ping()) -->
<property name="testOnReturn" value="true" />
<!-- idle状态监测用异步线程evict进行检查, -->
<property name="testWhileIdle" value="true" />
<!-- 一次最多evict的pool里的jedis实例个数 -->
<property name="numTestsPerEvictionRun" value="10" />
<!-- test idle 线程的时间间隔 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!--最大等待wait时间-->
<property name="maxWait" value="3000" />
<property name="whenExhaustedAction" value="" />
//WHEN_EXHAUSTED_FAIL = 0; 直接抛出异常throw new NoSuchElementException("Pool exhausted");
//WHEN_EXHAUSTED_BLOCK = 1;borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,
//如果请求阻塞超时,将抛出NoSuchElementException.如果maxWait为负数,请求将会无限制的阻
//塞下去,默认配置。
//WHEN_EXHAUSTED_GROW = 2;borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;
//
</bean>
public String set(String key, String value) {
Jedis jedis = null;
boolean success = true;
try {
jedis = this.pool.getResource();
return jedis.set(key, value);
}catch (JedisException e) {
success = false;
if(jedis != null){
pool.returnBrokenResource(jedis);
}
throw e;
}finally{
if(success && jedis != null){
this.pool.returnResource(jedis);
}
}
}
获取Jedis
pool.getResource();
这个可以直接看Pool的getResource方法,
最终还是GenericObjectPool的borrowObject()方法借用对象
@SuppressWarnings("unchecked")
public T getResource() {
try {
return (T) internalPool.borrowObject();
} catch (Exception e) {
throw new JedisConnectionException(
"Could not get a resource from the pool", e);
}
}
用完归还,调用的是GenericObjectPool的returnObject()方法
pool.returnResource(jedis)
//JedisPool.java
public void returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
}
//Pool.java
public void returnResourceObject(final Object resource) {
try {
internalPool.returnObject(resource);
} catch (Exception e) {
throw new JedisException(
"Could not return the resource to the pool", e);
}
}
出错,调用的是GenericObjectPool的invalidateObject()方法
最后在JedisFactory的destroyObject()中调用jedis.quit()请求Server关闭连接
pool.returnBrokenResource(jedis)
//JedisPool.java
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
}
//Pool.java
protected void returnBrokenResourceObject(final Object resource) {
try {
//失效
internalPool.invalidateObject(resource);
} catch (Exception e) {
throw new JedisException(
"Could not return the resource to the pool", e);
}
}
//GenericObjectPool
public void invalidateObject(Object obj)
throws Exception
{
try
{
if (this._factory != null)
this._factory.destroyObject(obj);
}
finally {
synchronized (this) {
this._numActive -= 1;
allocate();
}
}
}
//JedisFactory
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
JedisPool源代码
package redis.clients.jedis;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import redis.clients.util.Pool;
public class JedisPool extends Pool<Jedis> {
public JedisPool(final Config poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(String host, int port) {
this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final String host) {
this(host, Protocol.DEFAULT_PORT);
}
public JedisPool(final Config poolConfig, final String host, int port,
int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, final int port, final int timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password,
final int database) {
super(poolConfig, new JedisFactory(host, port, timeout, password, database));
}
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
}
public void returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
}
/**
* PoolableObjectFactory custom impl.
*/
private static class JedisFactory extends BasePoolableObjectFactory {
private final String host;
private final int port;
private final int timeout;
private final String password;
private final int database;
public JedisFactory(final String host, final int port,
final int timeout, final String password, final int database) {
super();
this.host = host;
this.port = port;
this.timeout = timeout;
this.password = password;
this.database = database;
}
public Object makeObject() throws Exception {
final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
jedis.connect();
if (null != this.password) {
jedis.auth(this.password);
}
if( database != 0 ) {
jedis.select(database);
}
return jedis;
}
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
public boolean validateObject(final Object obj) {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
try {
return jedis.isConnected();/* && jedis.ping().equals("PONG");*/
} catch (final Exception e) {
return false;
}
} else {
return false;
热心网友
时间:2024-08-18 22:51
1,JedisPool的使用
<!-- 连接池的配置信息 -->
<bean id="jedisConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 说明一个pool可以有多少个Jedis实例 -->
<property name="maxActive" value="10" />
<!-- 最大Idle-->
<property name="maxIdle" value="5" />
<!-- 最小Idle -->
<property name="minIdle" value="1" />
<!-- 获得一个jedis实例的时候是否检查连接可用性(ping()) -->
<property name="testOnBorrow" value="true" />
<!-- return 一个jedis实例给pool时,是否检查连接可用性(ping()) -->
<property name="testOnReturn" value="true" />
<!-- idle状态监测用异步线程evict进行检查, -->
<property name="testWhileIdle" value="true" />
<!-- 一次最多evict的pool里的jedis实例个数 -->
<property name="numTestsPerEvictionRun" value="10" />
<!-- test idle 线程的时间间隔 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!--最大等待wait时间-->
<property name="maxWait" value="3000" />
<property name="whenExhaustedAction" value="" />
//WHEN_EXHAUSTED_FAIL = 0; 直接抛出异常throw new NoSuchElementException("Pool exhausted");
//WHEN_EXHAUSTED_BLOCK = 1;borrowObject()将会阻塞,直到有可用新的或者空闲的object为止,或者如果配置了maxWait,
//如果请求阻塞超时,将抛出NoSuchElementException.如果maxWait为负数,请求将会无限制的阻
//塞下去,默认配置。
//WHEN_EXHAUSTED_GROW = 2;borrowObject()将会继续创建新的对象,并返回,因此,pool维护的对像数将超出maxActive;
//
</bean>
public String set(String key, String value) {
Jedis jedis = null;
boolean success = true;
try {
jedis = this.pool.getResource();
return jedis.set(key, value);
}catch (JedisException e) {
success = false;
if(jedis != null){
pool.returnBrokenResource(jedis);
}
throw e;
}finally{
if(success && jedis != null){
this.pool.returnResource(jedis);
}
}
}
获取Jedis
pool.getResource();
这个可以直接看Pool的getResource方法,
最终还是GenericObjectPool的borrowObject()方法借用对象
@SuppressWarnings("unchecked")
public T getResource() {
try {
return (T) internalPool.borrowObject();
} catch (Exception e) {
throw new JedisConnectionException(
"Could not get a resource from the pool", e);
}
}
用完归还,调用的是GenericObjectPool的returnObject()方法
pool.returnResource(jedis)
//JedisPool.java
public void returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
}
//Pool.java
public void returnResourceObject(final Object resource) {
try {
internalPool.returnObject(resource);
} catch (Exception e) {
throw new JedisException(
"Could not return the resource to the pool", e);
}
}
出错,调用的是GenericObjectPool的invalidateObject()方法
最后在JedisFactory的destroyObject()中调用jedis.quit()请求Server关闭连接
pool.returnBrokenResource(jedis)
//JedisPool.java
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
}
//Pool.java
protected void returnBrokenResourceObject(final Object resource) {
try {
//失效
internalPool.invalidateObject(resource);
} catch (Exception e) {
throw new JedisException(
"Could not return the resource to the pool", e);
}
}
//GenericObjectPool
public void invalidateObject(Object obj)
throws Exception
{
try
{
if (this._factory != null)
this._factory.destroyObject(obj);
}
finally {
synchronized (this) {
this._numActive -= 1;
allocate();
}
}
}
//JedisFactory
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
JedisPool源代码
package redis.clients.jedis;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import redis.clients.util.Pool;
public class JedisPool extends Pool<Jedis> {
public JedisPool(final Config poolConfig, final String host) {
this(poolConfig, host, Protocol.DEFAULT_PORT, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(String host, int port) {
this(new Config(), host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final String host) {
this(host, Protocol.DEFAULT_PORT);
}
public JedisPool(final Config poolConfig, final String host, int port,
int timeout, final String password) {
this(poolConfig, host, port, timeout, password, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, final int port) {
this(poolConfig, host, port, Protocol.DEFAULT_TIMEOUT, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, final int port, final int timeout) {
this(poolConfig, host, port, timeout, null, Protocol.DEFAULT_DATABASE);
}
public JedisPool(final Config poolConfig, final String host, int port, int timeout, final String password,
final int database) {
super(poolConfig, new JedisFactory(host, port, timeout, password, database));
}
public void returnBrokenResource(final BinaryJedis resource) {
returnBrokenResourceObject(resource);
}
public void returnResource(final BinaryJedis resource) {
returnResourceObject(resource);
}
/**
* PoolableObjectFactory custom impl.
*/
private static class JedisFactory extends BasePoolableObjectFactory {
private final String host;
private final int port;
private final int timeout;
private final String password;
private final int database;
public JedisFactory(final String host, final int port,
final int timeout, final String password, final int database) {
super();
this.host = host;
this.port = port;
this.timeout = timeout;
this.password = password;
this.database = database;
}
public Object makeObject() throws Exception {
final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
jedis.connect();
if (null != this.password) {
jedis.auth(this.password);
}
if( database != 0 ) {
jedis.select(database);
}
return jedis;
}
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
}
public boolean validateObject(final Object obj) {
if (obj instanceof Jedis) {
final Jedis jedis = (Jedis) obj;
try {
return jedis.isConnected();/* && jedis.ping().equals("PONG");*/
} catch (final Exception e) {
return false;
}
} else {
return false;
}
}
}
}