您的位置:首页 > 其它

JedisPool连接池实现难点

2015-07-03 23:22 211 查看
/article/4198961.html

【可改进的问题】
问题是jedispool有没有办法监控状态,比如说当前连接有多少,当前idle连接有多少,之类的同求。真心不想每次都构建连接然后在手动将连接返回池。

【JedisPool源码】

package redis.clients.jedis;

import org.apache.commons.pool.impl.GenericObjectPool.Config;

import redis.clients.util.Pool;

public class JedisPool extends Pool<Jedis>

{

public JedisPool(GenericObjectPool.Config poolConfig, String host)

{

this(poolConfig, host, 6379, 2000, null);

}

<strong> public JedisPool(String host, int port)

{

super(new GenericObjectPool.Config(), new JedisFactory(host, port, 2000, null));

}</strong>

<strong> public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout, String password)

{

super(poolConfig, new JedisFactory(host, port, timeout, password));

}</strong>

public JedisPool(GenericObjectPool.Config poolConfig, String host, int port)

{

this(poolConfig, host, port, 2000, null);

}

public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout)

{

this(poolConfig, host, port, timeout, null);

}

}

JedisPool继承了Pool,Pool的源码如下:

package redis.clients.util;

import org.apache.commons.pool.PoolableObjectFactory;

import org.apache.commons.pool.impl.GenericObjectPool;

import org.apache.commons.pool.impl.GenericObjectPool.Config;

import redis.clients.jedis.exceptions.JedisConnectionException;

import redis.clients.jedis.exceptions.JedisException;

public abstract class Pool<T>

{

private final GenericObjectPool internalPool;

public Pool(GenericObjectPool.Config poolConfig, PoolableObjectFactory factory)

{

this.internalPool = new GenericObjectPool(factory, poolConfig);

}

public T getResource()

{

try {

return this.internalPool.borrowObject();

} catch (Exception e) {

throw new JedisConnectionException("Could not get a resource from the pool", e);

}

}

public void returnResource(T resource)

{

try {

this.internalPool.returnObject(resource);

} catch (Exception e) {

throw new JedisException("Could not return the resource to the pool", e);

}

}

public void returnBrokenResource(T resource)

{

try {

this.internalPool.invalidateObject(resource);

} catch (Exception e) {

throw new JedisException("Could not return the resource to the pool", e);

}

}

public void destroy()

{

try {

this.internalPool.close();

} catch (Exception e) {

throw new JedisException("Could not destroy the pool", e);

}

}

}

至此我们已经清楚了,JedisPool使用了apache的GenericObjectPool来作为redis连接管理pool。GenericObjectPool的官方地址是:http://commons.apache.org/pool/

JedisFactory是PoolableObjectFactory的子类,PoolableObjectFactory提供了可以被Pool管理的对象的若干生命周期方法,JedisFactory的源码如下:

package redis.clients.jedis;

import org.apache.commons.pool.BasePoolableObjectFactory;

class JedisPool$JedisFactory extends BasePoolableObjectFactory

{

private final String host;

private final int port;

private final int timeout;

private final String password;

public JedisPool$JedisFactory(String host, int port, int timeout, String password)

{

this.host = host;

this.port = port;

this.timeout = ((timeout > 0) ? timeout : -1);

this.password = password;

}

public Object makeObject()

throws Exception

{

Jedis jedis;

if (this.timeout > 0)

jedis = new Jedis(this.host, this.port, this.timeout);

else {

jedis = new Jedis(this.host, this.port);

}

jedis.connect();

if (null != this.password) {

jedis.auth(this.password);

}

return jedis;

}

public void destroyObject(Object obj) throws Exception {

if (obj instanceof Jedis) {

Jedis jedis = (Jedis)obj;

if (!(jedis.isConnected())) return;

try {

try {

jedis.quit();

} catch (Exception e) {

}

jedis.disconnect();

}

catch (Exception e)

{

}

}

}

public boolean validateObject(Object obj) {

if (obj instanceof Jedis) {

Jedis jedis = (Jedis)obj;

try {

return ((jedis.isConnected()) && (jedis.ping().equals("PONG")));

} catch (Exception e) {

return false;

}

}

return false;

}

}

上面代码非常清楚地说明了JedisFactory如何构建、销毁、验证Jedis对象。这些生命周期方法会被GenericObjectPool 的borrowObject,returnObject,invalidateObject等方法调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: