龙空技术网

聊聊jedis连接池对commons-pool的封装

码匠乱炖 58

前言:

现时咱们对“nginxpooldestroy”可能比较注意,各位老铁们都想要剖析一些“nginxpooldestroy”的相关知识。那么小编同时在网上汇集了一些对于“nginxpooldestroy””的相关知识,希望同学们能喜欢,同学们快快来学习一下吧!

文本主要研究一下jedis连接池对commons-pool的封装

JedisPoolConfig

jedis-3.8.0-sources.jar!/redis/clients/jedis/JedisPoolConfig.java

public class JedisPoolConfig extends GenericObjectPoolConfig<Jedis> {  public JedisPoolConfig() {    // defaults to make your life with connection pool easier :)    setTestWhileIdle(true);    setMinEvictableIdleTimeMillis(60000);    setTimeBetweenEvictionRunsMillis(30000);    setNumTestsPerEvictionRun(-1);  }}

JedisPoolConfig继承了GenericObjectPoolConfig,在构造器里头设置了默认的参数,即testWhileIdle为true,minEvictableIdleTime为60s,timeBetweenEvictionRuns为30s,numTestsPerEvictionRun为-1

JedisFactory

见上一篇文章聊聊JedisFactory

Pool

jedis-3.8.0-sources.jar!/redis/clients/jedis/util/Pool.java

public abstract class Pool<T> implements Closeable {  /**   * @deprecated This will be private in future.   */  @Deprecated  protected GenericObjectPool<T> internalPool;  public Pool(final GenericObjectPoolConfig<T> poolConfig, PooledObjectFactory<T> factory) {    initPool(poolConfig, factory);  }  /**   * @param poolConfig   * @param factory   * @deprecated This method will be private in future.   */  @Deprecated  public void initPool(final GenericObjectPoolConfig<T> poolConfig, PooledObjectFactory<T> factory) {    if (this.internalPool != null) {      try {        closeInternalPool();      } catch (Exception e) {      }    }    this.internalPool = new GenericObjectPool<>(factory, poolConfig);  }  public T getResource() {    try {      return internalPool.borrowObject();    } catch (NoSuchElementException nse) {      if (null == nse.getCause()) { // The exception was caused by an exhausted pool        throw new JedisExhaustedPoolException(            "Could not get a resource since the pool is exhausted", nse);      }      // Otherwise, the exception was caused by the implemented activateObject() or ValidateObject()      throw new JedisException("Could not get a resource from the pool", nse);    } catch (Exception e) {      throw new JedisConnectionException("Could not get a resource from the pool", e);    }  }  public void returnResource(final T resource) {    if (resource != null) {      returnResourceObject(resource);    }  }  /**   * @param resource   * @deprecated This will be removed in next major release. Use {@link Pool#returnResource(java.lang.Object)}.   */  @Deprecated  protected void returnResourceObject(final T resource) {    try {      internalPool.returnObject(resource);    } catch (RuntimeException e) {      throw new JedisException("Could not return the resource to the pool", e);    }  }  public void destroy() {    closeInternalPool();  }/**   * @deprecated This will be removed in next major release. Use {@link Pool#destroy()}.   */  @Deprecated  protected void closeInternalPool() {    try {      internalPool.close();    } catch (RuntimeException e) {      throw new JedisException("Could not destroy the pool", e);    }  }  /**   * @param resource   * @deprecated This will be removed in next major release. Use {@link Pool#returnBrokenResource(java.lang.Object)}.   */  @Deprecated  protected void returnBrokenResourceObject(final T resource) {    try {      internalPool.invalidateObject(resource);    } catch (Exception e) {      throw new JedisException("Could not return the broken resource to the pool", e);    }  }  //......}  

Pool声明实现Closeable接口,它的构造器根据GenericObjectPoolConfig和PooledObjectFactory来创建GenericObjectPool,它的getResource、returnResource、returnBrokenResourceObject、destroy方法内部都是委托给了GenericObjectPool

它有一个实现类JedisPoolAbstract,而JedisPoolAbstract还有两个子类,分别是JedisPool、JedisSentinelPool

JedisPoolAbstract

jedis-3.8.0-sources.jar!/redis/clients/jedis/JedisPoolAbstract.java

/** * @deprecated This class will be removed in future. If you are directly manipulating this class, * you are suggested to change your code to use {@link Pool Pool<Jedis>} instead. */@Deprecatedpublic class JedisPoolAbstract extends Pool<Jedis> {  /**   * Using this constructor means you have to set and initialize the internalPool yourself.   *   * @deprecated This constructor will be removed in future.   */  @Deprecated  public JedisPoolAbstract() {    super();  }  public JedisPoolAbstract(GenericObjectPoolConfig<Jedis> poolConfig,      PooledObjectFactory<Jedis> factory) {    super(poolConfig, factory);  }}

这个类未来将要被废弃,它主要是设置了Pool的泛型为Jedis

JedisPool

jedis-3.8.0-sources.jar!/redis/clients/jedis/JedisPool.java

public class JedisPool extends JedisPoolAbstract {  //......  @Override  public Jedis getResource() {    Jedis jedis = super.getResource();    jedis.setDataSource(this);    return jedis;  }  @Override  public void returnResource(final Jedis resource) {    if (resource != null) {      try {        resource.resetState();        returnResourceObject(resource);      } catch (RuntimeException e) {        returnBrokenResource(resource);        log.warn("Resource is returned to the pool as broken", e);      }    }  }}  

JedisPool覆盖了getResource和returnResource方法,其中getResource新增了设置dataSource给jedis;returnResource方法新增了jedis的resetState操作,return有异常的话会执行returnBrokenResource

JedisSentinelPool

jedis-3.8.0-sources.jar!/redis/clients/jedis/JedisSentinelPool.java

public class JedisSentinelPool extends JedisPoolAbstract {  @Override  public Jedis getResource() {    while (true) {      Jedis jedis = super.getResource();      jedis.setDataSource(this);      // get a reference because it can change concurrently      final HostAndPort master = currentHostMaster;      final HostAndPort connection = new HostAndPort(jedis.getClient().getHost(), jedis.getClient()          .getPort());      if (master.equals(connection)) {        // connected to the correct master        return jedis;      } else {        returnBrokenResource(jedis);      }    }  }  @Override  public void returnResource(final Jedis resource) {    if (resource != null) {      try {        resource.resetState();        returnResourceObject(resource);      } catch (RuntimeException e) {        returnBrokenResource(resource);        log.debug("Resource is returned to the pool as broken", e);      }    }  }  //......}

JedisSentinelPool覆盖了getResource和returnResource方法,其中getResource新增了设置dataSource给jedis,然后判断master;returnResource方法新增了jedis的resetState操作,return有异常的话会执行returnBrokenResource

小结

jedis主要有三个对象对commons-pool进行包装,分别是JedisPoolConfig(继承了GenericObjectPoolConfig),JedisFactory(实现了PooledObjectFactory<Jedis>接口)、Pool(提供了get和return方法,内部委托给GenericObjectPool)

JedisPoolConfig继承了GenericObjectPoolConfig,在构造器里头设置了默认的参数,即testWhileIdle为true,minEvictableIdleTime为60s,timeBetweenEvictionRuns为30s,numTestsPerEvictionRun为-1

标签: #nginxpooldestroy