Commons pool2 配置詳解及其在Jedis中的使用

westwolf發表於2021-09-09

Commons pool2配置引數(以Jedis連線為例)

  • MaxTotal: 最大連線數(空閒+使用中)

  • MaxIdle: 最大空閒連線數

  • MinIdle:  最小空閒連線數

  • MaxWaitMillis: 借出連線時最大的等待時間,超時拋錯

  • TimeBetweenEvictionRunsMillis: 後臺檢測執行緒週期

  • MinEvictableIdleTimeMillis:硬閒置時間,連線多久沒有使用設定為閒置,檢測執行緒直接剔除閒置,為保持最小空閒數,被剔除後可能重新生成

  • SoftMinEvictableIdleTimeMillis:軟閒置時間,連線多久沒有使用設定為閒置,當空閒連線 > MinIdle,才執行剔除閒置,否則維持最小空閒數,即使閒置了也不會剔除,設定MinEvictableIdleTimeMillis後,本引數無效

  • testOnBorrow:在borrow一個連線時,是否提前進行alidate操作;如果為true,則得到的jedis例項均是可用的;

  • testOnReturn:在連線return給pool時,是否提前進行validate操作;

  • testWhileIdle:如果為true,表示後臺執行緒對idle連線進行掃描,如果validate失敗,此連線會被從pool中剔除;只有在timeBetweenEvictionRunsMillis大於0時才有意義;

JedisPool驗證引數配置

用以下程式碼驗證配置引數的作用,其中Ctg開頭的是我封裝了的,可以使用JedisPool相關類代替

public static void main(String[] args) {
        BasicConfigurator.configure();

        List<HostAndPort> hostAndPortList = new ArrayList(); //地址列表
        HostAndPort host1 = new HostAndPort("132.122.232.225",9081); 
        hostAndPortList.add(host1);

        GenericObjectPoolConfig poolConfig = new JedisPoolConfig(); //執行緒池配置
        poolConfig.setMaxIdle(2); //最大空閒連線數
        poolConfig.setMaxTotal(3); // 最大連線數(空閒+使用中)
        poolConfig.setMinIdle(1); //保持的最小空閒連線數
        poolConfig.setMaxWaitMillis(2000); //借出連線時最大的等待時間
        poolConfig.setTimeBetweenEvictionRunsMillis(1000); //1秒執行一次檢測執行緒
        //硬閒置、軟閒置配置
        //硬閒置  3秒沒有佔用設定為閒置, 檢測執行緒直接剔除閒置,保持的最小空閒數,會被剔除且重新生成
        poolConfig.setMinEvictableIdleTimeMillis(3000);        //軟閒置  3秒沒有佔用設定為閒置, 當空閒連線>最小空閒數,才執行剔除閒置連線,否則維持最小空閒數,即使閒置了也不會剔除
        poolConfig.setSoftMinEvictableIdleTimeMillis(3000);

        CtgJedisPoolConfig config = new CtgJedisPoolConfig(hostAndPortList);
        config.setDatabase(4970) //分組對應的桶位
                .setPassword("disk#Test1234") // “使用者#密碼”
                .setPoolConfig(poolConfig) //執行緒池配置
                .setPeriod(1000)  //後臺監控執行週期,毫秒
                .setMonitorTimeout(100);  //後臺監控ping命令超時時間,毫秒

        CtgJedisPool pool = new CtgJedisPool(config); //建立連線池
        ProxyJedis jedis_1 = null;
        ProxyJedis jedis_2 = null;
        ProxyJedis jedis_3 = null;        //最大連線為3,以下三次獲取能成功
        try {
            logger.info("=================== get jedis_1 =========================");
            jedis_1 = pool.getResource();
        } catch (CtgJedisPoolException e) {
            logger.error("jedis_1 : Get resource error");
        }        try {
            logger.info("=================== get jedis_2 =========================");
            jedis_2 = pool.getResource();
        } catch (CtgJedisPoolException e) {
            logger.error("jedis_2 : Get resource error");
        }        try {
            logger.info("=================== get jedis_3 =========================");
            jedis_3 = pool.getResource();
        } catch (CtgJedisPoolException e) {
            logger.error("jedis_3 : Get resource error");
        }        //第四次獲取連線,失敗。獲取連線超時時間為2秒,重試一次,正確結果應該為4秒
        ProxyJedis jedis_4 = null;        long startTime = 0L;        try {
            logger.info("=================== get jedis_4 =========================");
            startTime = System.currentTimeMillis();
            jedis_4 = pool.getResource();
            logger.info("Get resource cost time : " + (System.currentTimeMillis() - startTime));
        } catch (CtgJedisPoolException e) {
            logger.info("Get resource cost time : " + (System.currentTimeMillis() - startTime));
            logger.error("jedis_4 : Get resource error");
        }        // 歸還一個連線,空閒連線數:1 活躍連線數:2,
        // 等待後臺執行剔除空閒連線,當前空閒連線數 = 需要保持最小空閒連線數,不會進行剔除,
        // 硬閒置情況下達到限制時間,會被剔除
        try{
            logger.info("=================== close jedis_1 =========================");
            jedis_1.close();  //歸還連線至連線池
        } catch (Throwable e) {

        }        try {
            logger.info("============== Sleep 10 ===============");
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        // 繼續歸還一個連線,空閒連線數:2 活躍連線數:1,
        // 等待後臺執行剔除空閒連線,當前空閒連線數 > 需要保持最小空閒連線數,進行剔除
        try{
            logger.info("=================== close jedis_2 =========================");
            jedis_2.close();  //歸還連線至連線池
        } catch (Throwable e) {

        }        try {
            logger.info("============== Sleep 9 ===============");
            Thread.sleep(9000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        logger.info("-------------------------------pool close-----------------------------------");
        pool.close(); //關閉連線池
    }

poolConfig.setMinEvictableIdleTimeMillis(3000);
硬閒置配置輸出結果

# 前三次獲取成功=================== get jedis_1 =========================
- makeJedis-- 132.122.232.225:9081- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 0 NumIdle: 0 NumWaiters: 0}
- =================== get jedis_2 =========================
- makeJedis-- 132.122.232.225:9081- =================== get jedis_3 =========================
- makeJedis-- 132.122.232.225:9081# 達到最大連線數,第四次獲取失敗,失敗時間為4,與預期相同# NumWaiters = 1- =================== get jedis_4 =========================
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 3 NumIdle: 0 NumWaiters: 1}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 3 NumIdle: 0 NumWaiters: 1}
- Get jedis from ableNodes error at 132.122.232.225:9081 :Could not get a resource from the pool
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 3 NumIdle: 0 NumWaiters: 1}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 3 NumIdle: 0 NumWaiters: 1}
- Get jedis from ableNodes error at 132.122.232.225:9081 :Could not get a resource from the pool
- Get resource cost time : 4003- jedis_4 : Get resource error# 歸還一個連線- =================== close jedis_1 =========================
- ============== Sleep 10 ===============
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒硬閒置時間,剔除,重新 makeJedis- makeJedis-- 132.122.232.225:9081- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒硬閒置時間,剔除,重新 makeJedis- makeJedis-- 132.122.232.225:9081- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# 歸還第二個連線- =================== close jedis_2 =========================
- ============== Sleep 9 ===============# 未超過最大空閒連線數2,NumIdle+1 = 2- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 2 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 2 NumWaiters: 0}# 到達3秒硬閒置時間,剔除,NumIdle - 1 = 1 = minIdle,不需要 makeJedis- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒硬閒置時間,剔除,重新 makeJedis- makeJedis-- 132.122.232.225:9081- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒硬閒置時間,剔除,重新 makeJedis- makeJedis-- 132.122.232.225:9081- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- -------------------------------pool close-----------------------------------

poolConfig.setSoftMinEvictableIdleTimeMillis(3000);
軟閒置配置輸出結果

# 省略前面相同部分# 歸還一個連線- =================== close jedis_1 =========================
- ============== Sleep 10 ===============
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒軟閒置時間,但 NumIdle = minIdle 不剔除,沒有makeJedis日誌輸出- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒軟閒置時間,但 NumIdle = minIdle 不剔除,沒有makeJedis日誌輸出- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 2 NumIdle: 1 NumWaiters: 0}# 歸還第二個連線- =================== close jedis_2 =========================
- ============== Sleep 9 ===============# 未超過最大空閒連線數2,NumIdle+1 = 2- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 2 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 2 NumWaiters: 0}# NumIdle: 2到達3秒軟閒置時間,NumIdle > minIdle 剔除,- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒軟閒置時間,但 NumIdle = minIdle 不剔除,沒有makeJedis日誌輸出- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}# NumIdle: 1到達3秒軟閒置時間,但 NumIdle = minIdle 不剔除,沒有makeJedis日誌輸出- nodePoolMap: {132.122.232.225:9081=132.122.232.225:9081 NumActive: 1 NumIdle: 1 NumWaiters: 0}
- -------------------------------pool close-----------------------------------

從上述日誌輸出,驗證了各引數的作用,其中 軟閒置、硬閒置配置的區別,在於剔除閒置連線時,是否需要考慮當前 空閒連線與minIdle的大小關係。

此外,同時配置了軟、硬閒置引數以後,輸出結果與單獨配置硬閒置引數相同,即
設定MinEvictableIdleTimeMillis後,SoftMinEvictableIdleTimeMillis引數無效



作者:峰巢
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4662/viewspace-2818096/,如需轉載,請註明出處,否則將追究法律責任。

相關文章