Redis:Jedis連接池JedisPool

目錄

1、JedisPool的應用

1.1 基本應用

1.2 封裝應用

1.3 增加超時重試

2、JedisPool配置

2.1 工廠配置

2.2 資源池配置


  Jedis提供了連接池JedisPool。由於Jedis對象不是線程安全的,所以一般會從連接池中取出一個Jedis對象獨佔,使用完畢後再歸還給連接池。

    maven依賴:

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.1.0</version>
</dependency>

1、JedisPool的應用

1.1 基本應用

    資源池簡單應用代碼示例:

// 獲取連接池
JedisPool pool = new JedisPool();
// 從資源池中拿出可以鏈接對象
// 用try-with-resource自動調用close方法歸還資源
try(Jedis jedis = pool.getResource();) {
// 應用程序執行操作

}

1.2 封裝應用

    上述寫法,如果使用者沒有使用try-with-resource並且忘記了歸還資源,可以對JedisPool做一層封裝,將歸還資源的操作封裝起來。

1、資源池:

public class RedisPool {

    private JedisPool pool;

    public RedisPool() {
        this.pool = new JedisPool();
    }

    /**
     * 執行任務
     *
     * @param callable
     */
    public void execute(RedisCallable callable) {
        try(Jedis jedis = pool.getResource()) {
            callable.call(jedis);
        }
    }
}

2、回調接口:

public interface RedisCallable {

    /**
     * 回調方法,執行需要執行的任務
     *
     * @param jedis jedis
     */
    void call(Jedis jedis);
}

3、使用:

public class RedisMain {

    public static void main(String[] args) {
        RedisPool pool = new RedisPool();
        pool.execute((jedis) -> {
            System.out.println(jedis.get("key"));
        });
    }
}

1.3 增加超時重試

    網絡抖動情況下,需要增加超時重試機制,在捕獲到JedisConnectionException時可以進行重試。

    可以按如下方式改造資源池:

public class RedisPool {

    /**
     * 最大重試次數
     */
    private static final int MAX_RETRY = 3;

    private JedisPool pool;

    public RedisPool() {
        this.pool = new JedisPool();
    }

    /**
     * 執行任務
     *
     * @param callable
     */
    public void execute(RedisCallable callable) {
        int count = 0;
        try (Jedis jedis = pool.getResource()) {
            execute(callable, jedis, count);
        }
    }

    private void execute(RedisCallable callable, Jedis jedis, int count) {
        try {
            callable.call(jedis);
        } catch (JedisConnectionException e) {
            if (count < MAX_RETRY) {
                execute(callable, jedis, ++count);
            } else {
                throw e;
            }
        }
    }
}

2、JedisPool配置

    JedisPool入參最多的構造器:

  public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
      final int connectionTimeout, final int soTimeout, final String password, final int database,
      final String clientName) {
    super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
        database, clientName));
  }

    上述參數可以分成兩部分:資源池配置,以及工廠配置。

2.1 工廠配置

    JedisFactory的主要功能爲管理(創建,關閉,驗證)redis的連接客戶端jedis。從連接池獲取jedis連接資源,實際上看是從JedisPool的父類pool中獲取,而pool又委託給JedisFactory,最後由JedisFactory創建redis連接客戶端jedis。

  1. host:目標服務實例的域名或ip
  2. port:目標服務器的端口(Redis默認端口號是6379)
  3. connectionTimeout:連接超時時間
  4. soTimeout:socket超時時間
  5. password:密碼
  6. database:數據庫
  7. clientName:生產的客戶端實例名稱

2.2 資源池配置

    資源池JedisPool使用GenericObjectPool的實例來傳入配置,而GenericObjectPool是BaseGenericObjectPool的子類。

    核心參數:

  • maxTotal:最大連接數;
  • maxIdle:最大空閒連接數;
  • minIdle:最小空閒連接數;
  • blockWhenExhausted:表示當pool中的jedis實例都被分配完時,是否要進行阻塞;
  • maxWaitMillis:當blockWhenExhausted爲true時,最大的阻塞時長。

    空閒連接資源檢測相關:

  • testOnCreate:在創建Jedis實例時,測試連接可用性,默認關閉,如果打開,則保證創建的都是連接可用的Jedis實例;
  • testOnBorrow:在資源池借出Jedis實例時,測試連接可用性,默認關閉,如果打開,則保證借出的都是可用的;
  • testOnReturn:在Jedis歸還Jedis資源池時,測試連接可用性,默認關閉;
  • testWhileIdle:表示有一個idle object evitor線程對空閒的Jedis實例進行掃描,如果驗證失敗,此Jedis實例會被從資源池中刪除掉;這一項只有在timeBetweenEvictionRunsMillis大於0時纔有意義。

    空閒連接資源驅逐相關:

  • timeBetweenEvictionRunsMillis:表示idle object evitor兩次掃描之間要sleep的毫秒數;
  • numTestsPerEvictionRun:表示idle object evitor每次掃描的最多的對象數;
  • minEvictableIdleTimeMillis:空閒驅逐時間,表示一個對象至少停留在idle狀態的最短時間,然後才能被idle object evitor掃描並驅逐;這一項只有在timeBetweenEvictionRunsMillis大於0時纔有意義;
  • softMinEvictableIdleTimeMillis:軟空閒驅逐時間,在minEvictableIdleTimeMillis基礎上,還需要檢測至少minIdle個對象已經在資源池裏,纔會進行驅逐;
  • lifo:當借出的資源時,是使用LIFO(last in first out)策略,借出最新使用的資源;還是使用FIFO策略,借出最久沒有使用的資源。默認爲true,即LIFO;
  • evictionPolicy:驅逐策略,接口,默認實現邏輯:資源的空閒毫秒數,如果大於空閒驅逐時間minEvictableIdleTimeMillis,或大於softMinEvictableIdleTimeMillis且當前的空閒資源數量大於配置的最小空閒資源數量,則進行驅逐

    BaseGenericObjectPool的配置如下:

    private volatile int maxTotal =
            GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
    private volatile boolean blockWhenExhausted =
            BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
    private volatile long maxWaitMillis =
            BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
    private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
    private final boolean fairness;
    private volatile boolean testOnCreate =
            BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
    private volatile boolean testOnBorrow =
            BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
    private volatile boolean testOnReturn =
            BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
    private volatile boolean testWhileIdle =
            BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
    private volatile long timeBetweenEvictionRunsMillis =
            BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    private volatile int numTestsPerEvictionRun =
            BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    private volatile long minEvictableIdleTimeMillis =
            BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    private volatile long softMinEvictableIdleTimeMillis =
            BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    private volatile EvictionPolicy<T> evictionPolicy;
    private volatile long evictorShutdownTimeoutMillis =
            BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;

    GenericObjectPool的配置如下:

    /**
     * The default value for the {@code maxTotal} configuration attribute.
     * @see GenericObjectPool#getMaxTotal()
     */
    public static final int DEFAULT_MAX_TOTAL = 8;

    /**
     * The default value for the {@code maxIdle} configuration attribute.
     * @see GenericObjectPool#getMaxIdle()
     */
    public static final int DEFAULT_MAX_IDLE = 8;

    /**
     * The default value for the {@code minIdle} configuration attribute.
     * @see GenericObjectPool#getMinIdle()
     */
    public static final int DEFAULT_MIN_IDLE = 0;


    private int maxTotal = DEFAULT_MAX_TOTAL;

    private int maxIdle = DEFAULT_MAX_IDLE;

    private int minIdle = DEFAULT_MIN_IDLE;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章