• JedisPool连接池实现难点


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

    【JedisPool源码】

    1. package redis.clients.jedis;  
    2.   
    3. import org.apache.commons.pool.impl.GenericObjectPool.Config;  
    4. import redis.clients.util.Pool;  
    5.   
    6. public class JedisPool extends Pool<Jedis>  
    7. {  
    8.   public JedisPool(GenericObjectPool.Config poolConfig, String host)  
    9.   {  
    10.     this(poolConfig, host, 6379, 2000, null);  
    11.   }  
    12.   
    13. <strong>  public JedisPool(String host, int port)  
    14.   {  
    15.     super(new GenericObjectPool.Config(), new JedisFactory(host, port, 2000, null));  
    16.   }</strong>  
    17.   
    18. <strong>  public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout, String password)  
    19.   {  
    20.     super(poolConfig, new JedisFactory(host, port, timeout, password));  
    21.   }</strong>  
    22.   
    23.   public JedisPool(GenericObjectPool.Config poolConfig, String host, int port)  
    24.   {  
    25.     this(poolConfig, host, port, 2000, null);  
    26.   }  
    27.   
    28.   public JedisPool(GenericObjectPool.Config poolConfig, String host, int port, int timeout)  
    29.   {  
    30.     this(poolConfig, host, port, timeout, null);  
    31.   }  
    32. }  

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

    1. package redis.clients.util;  
    2.   
    3. import org.apache.commons.pool.PoolableObjectFactory;  
    4. import org.apache.commons.pool.impl.GenericObjectPool;  
    5. import org.apache.commons.pool.impl.GenericObjectPool.Config;  
    6. import redis.clients.jedis.exceptions.JedisConnectionException;  
    7. import redis.clients.jedis.exceptions.JedisException;  
    8.   
    9. public abstract class Pool<T>  
    10. {  
    11.   private final GenericObjectPool internalPool;  
    12.   
    13.   public Pool(GenericObjectPool.Config poolConfig, PoolableObjectFactory factory)  
    14.   {  
    15.     this.internalPool = new GenericObjectPool(factory, poolConfig);  
    16.   }  
    17.   
    18.   public T getResource()  
    19.   {  
    20.     try {  
    21.       return this.internalPool.borrowObject();  
    22.     } catch (Exception e) {  
    23.       throw new JedisConnectionException("Could not get a resource from the pool", e);  
    24.     }  
    25.   }  
    26.   
    27.   public void returnResource(T resource)  
    28.   {  
    29.     try {  
    30.       this.internalPool.returnObject(resource);  
    31.     } catch (Exception e) {  
    32.       throw new JedisException("Could not return the resource to the pool", e);  
    33.     }  
    34.   }  
    35.   
    36.   public void returnBrokenResource(T resource)  
    37.   {  
    38.     try {  
    39.       this.internalPool.invalidateObject(resource);  
    40.     } catch (Exception e) {  
    41.       throw new JedisException("Could not return the resource to the pool", e);  
    42.     }  
    43.   }  
    44.   
    45.   public void destroy()  
    46.   {  
    47.     try {  
    48.       this.internalPool.close();  
    49.     } catch (Exception e) {  
    50.       throw new JedisException("Could not destroy the pool", e);  
    51.     }  
    52.   }  
    53. }  

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

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

    1. package redis.clients.jedis;  
    2.   
    3. import org.apache.commons.pool.BasePoolableObjectFactory;  
    4.   
    5. class JedisPool$JedisFactory extends BasePoolableObjectFactory  
    6. {  
    7.   private final String host;  
    8.   private final int port;  
    9.   private final int timeout;  
    10.   private final String password;  
    11.   
    12.   public JedisPool$JedisFactory(String host, int port, int timeout, String password)  
    13.   {  
    14.     this.host = host;  
    15.     this.port = port;  
    16.     this.timeout = ((timeout > 0) ? timeout : -1);  
    17.     this.password = password;  
    18.   }  
    19.   
    20.   public Object makeObject()  
    21.     throws Exception  
    22.   {  
    23.     Jedis jedis;  
    24.     if (this.timeout > 0)  
    25.       jedis = new Jedis(this.host, this.port, this.timeout);  
    26.     else {  
    27.       jedis = new Jedis(this.host, this.port);  
    28.     }  
    29.   
    30.     jedis.connect();  
    31.     if (null != this.password) {  
    32.       jedis.auth(this.password);  
    33.     }  
    34.     return jedis;  
    35.   }  
    36.   
    37.   public void destroyObject(Object obj) throws Exception {  
    38.     if (obj instanceof Jedis) {  
    39.       Jedis jedis = (Jedis)obj;  
    40.       if (!(jedis.isConnected())) return;  
    41.       try {  
    42.         try {  
    43.           jedis.quit();  
    44.         } catch (Exception e) {  
    45.         }  
    46.         jedis.disconnect();  
    47.       }  
    48.       catch (Exception e)  
    49.       {  
    50.       }  
    51.     }  
    52.   }  
    53.   
    54.   public boolean validateObject(Object obj) {  
    55.     if (obj instanceof Jedis) {  
    56.       Jedis jedis = (Jedis)obj;  
    57.       try {  
    58.         return ((jedis.isConnected()) && (jedis.ping().equals("PONG")));  
    59.       } catch (Exception e) {  
    60.         return false;  
    61.       }  
    62.     }  
    63.     return false;  
    64.   }  
    65. }  
     上面代码非常清楚地说明了JedisFactory如何构建、销毁、验证Jedis对象。这些生命周期方法会被GenericObjectPool 的borrowObject,returnObject,invalidateObject等方法调用。
  • 相关阅读:
    五场面试之后的小结
    玩转ubuntu之初体验
    现阶段规划小结
    高并发秒杀系统--课程总结与思考
    高并发秒杀系统--秒杀高并发分析与解决方案
    高并发秒杀系统--SpringMVC整合
    高并发秒杀系统--Service事务管理与继承测试
    高并发秒杀系统--Service接口设计与实现
    对于你为什么要离职的深入思考
    两场面试之后的小结
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4619948.html
Copyright © 2020-2023  润新知