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


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

    JedisPoolConfig

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

    public class JedisPoolConfig extends GenericObjectPoolConfig {
      public JedisPoolConfig() {
        // defaults to make your life with connection pool easier :)
        setTestWhileIdle(true);
        setMinEvictableIdleTimeMillis(60000);
        setTimeBetweenEvictionRunsMillis(30000);
        setNumTestsPerEvictionRun(-1);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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 implements Closeable {
    
      /**
       * @deprecated This will be private in future.
       */
      @Deprecated
      protected GenericObjectPool internalPool;
    
      public Pool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory factory) {
        initPool(poolConfig, factory);
      }
    
      /**
       * @param poolConfig
       * @param factory
       * @deprecated This method will be private in future.
       */
      @Deprecated
      public void initPool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory 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);
        }
      }
    
      //......
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    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.
     */
    @Deprecated
    public class JedisPoolAbstract extends Pool {
    
      /**
       * 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 poolConfig,
          PooledObjectFactory factory) {
        super(poolConfig, factory);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这个类未来将要被废弃,它主要是设置了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);
          }
        }
      }
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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);
          }
        }
      }
    
      //......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

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

    小结

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

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

  • 相关阅读:
    Python GUI案例之看图猜成语开发(第一篇)
    面试总结:H5 移动 web 开发(H5 新特性、CSS3 新特性、如何实现双飞翼(圣杯)布局)
    控制台警报:DevTools failed to load SourceMap
    第15节-PhotoShop基础课程-吸取工具组
    《Linux驱动:s3c2440 lcd 驱动分析》
    DRF中的模型序列化是什么
    NCV1117ST50T3G线性稳压器芯片中文资料规格书PDF数据手册引脚图图片价格参数
    2022-01-08 如何高质量完成需求开发
    创建SpringBoot工程
    【Redis学习笔记】redis-trib.rb命令详解
  • 原文地址:https://blog.csdn.net/hello_ejb3/article/details/133043593