Jedis連接池的使用方法

??Jedis有直連方式,所謂直連指的是Jedis每次都會新建TCP連接,使用后在斷開連接,對于平凡訪問Redis的場景顯然不是高效的使用方式,如圖:


Jedis直連redis

??因此生產(chǎn)環(huán)境一般使用連接池的方式對Jedis連接池進行管理,如圖:


Jedis連接池使用方式

??Jedis對象預(yù)先放在池子中(JedisPool),每次要連接Redis,只需要在池子中借,用完了在歸還給池子。

??客戶端連接Redis使用的是TCP協(xié)議,直連的方式每次需要建立TCP連接,而連接池的方式是可以預(yù)先初始化好Jedis連接,所以每次只需要從Jedis連接池借用即可,而借用和歸還操作是在本地進行的,只有少量的并發(fā)同步開銷,遠遠小于新建TCP連接的開銷。另外直連的方式無法限制Jedis對象的個數(shù),在極端情況下可能會造成連接泄漏,而連接池的形式可以有效的保護和控制資源的使用。但是直連的方式也并不是一無是處,下表給出兩種方式各自的優(yōu)劣勢:

  • 直連 ?優(yōu)點:簡單方便,適用于少量長期連接的場景,缺點:1>存在每次新建/關(guān)閉TCP連接開銷。2>資源無法控制,極端情況會出現(xiàn)連接泄漏。3>Jedis對象線程不安全。
  • 連接池?優(yōu)點:1>無需每次連接都生成Jedis對象,降低開銷。2>使用連接池的形式保護和控制資源的使用。缺點:相對于直連,使用相對麻煩,尤其在資源的管理上需要很多參數(shù)來保證,一旦不合理也會出現(xiàn)問題。

??Jedis提供了JedisPool這個類作為對Jedis的連接池,同時使用了Apache的通用對象池工具common-pool作為資源的管理工具,下面是使用JedisPool操作Redis的代碼示例:
1)Jedis連接池(通常JedisPool是單例的):
//common-pool連接池配置,這里使用默認配置,后面小節(jié)會介紹具體配置說明
GenericObjectPoolConfig poolConfig=new GenericObjectPoolConfig();
//初始化Jedis連接池
JedisPool jedisPool=new JedisPool(poolConfig,"127.0.0.1",6379);

  1. 獲取Jedis對象不再是直接生成一個Jedis對象進行直連,而是從連接池直接獲取,代碼如下:
Jedis jedis =null;
try {
  //1.從連接池獲取jedis對象
  jedis=jedisPool.getResource();
  //2.執(zhí)行操作
   jedis.get("hello");
} catch (Exception e) {
  logger.error(e.getMessage(),e);
}finally{
  if(jedis!=null){
    //如果使用JedisPool,close操作不是關(guān)閉連接,代表歸還連接池
    jedis.close();
  }
}

??這里可以看到finally中依然是jedis.close()操作,為什么會把連接關(guān)閉呢,這不和連接池的原則違背嗎?但實際上Jedis的close()實現(xiàn)方式如下:

public void close(){
  //使用Jedis連接池
  if(dataSource!=null){
    if(client.isBroken()){
      this.dataSource.returnBrokenResource(this);
    }else{
      this.dataSource.returnResource(this);
    }
 //直連
  }else{
    client.close();
  }
}

參數(shù)說明:

  • dataSource!=null代表使用的是連接池,所以jedis.close()代表歸還連接給連接池,而且Jedis會判斷當前連接是否已經(jīng)斷開。
  • dataSource=null代表直連,jedis.close()代表關(guān)閉連接。
    ??前面GenericObjectPoolConfig使用的是默認配置,實際它提供有很多參數(shù),例如池子中最大連接數(shù),最大空閑連接數(shù),最小空閑連接數(shù),連接活性檢測,等等,例如下面代碼:
GenericObjectPoolConfig poolConfig=new GenericObjectPoolConfig();
//設(shè)置最大連接數(shù)為默認值的5倍
poolConfig.setMaxTotal(GenericObjectPoolConfig.DEFAULT_MAX_TOTAL*5);
//設(shè)置最大空閑連接數(shù)為默認值的3倍
poolConfig.setMaxIdle(GenericObjectPoolConfig.DEFAULT_MAX_IDLE*3);
//設(shè)置最小空閑連接數(shù)為默認值的2倍
poolConfig.setMinIdle(GenericObjectPoolConfig. DEFAULT_MIN_IDLE*2);
//設(shè)置開啟JMX功能
poolConfig.SetJmxEnabled(true);
//設(shè)置連接池沒有連接后客戶端的最大等待時間(單位為毫秒)
poolConfig.setMaxWaitMillis(3000);

GenericObjectPoolConfig的其他屬性:

基本參數(shù)
lifo ?//GenericObjectPool 提供了后進先出(LIFO)與先進先出(FIFO)兩種行為模式的池。默認為true,即當池中有空閑可用的對象時,調(diào)用borrowObject方法會返回最近(后進)的實例
fairness ?//當從池中獲取資源或者將資源還回池中時 是否使用java.util.concurrent.locks.ReentrantLock.ReentrantLock 的公平鎖機制,默認為false

數(shù)量控制參數(shù)
maxTotal ?//鏈接池中最大連接數(shù),默認為8
maxIdle ?//鏈接池中最大空閑的連接數(shù),默認也為8
minIdle ?//連接池中最少空閑的連接數(shù),默認為0

超時參數(shù)
maxWaitMillis ?//當連接池資源耗盡時,等待時間,超出則拋異常,默認為-1即永不超時
blockWhenExhausted ?//連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true。當這個值為true的時候,maxWaitMillis參數(shù)才能生效。為false的時候,當連接池沒資源,則立馬拋異常。默認為true

test參數(shù)
testOnCreate ?//默認false,create的時候檢測是有有效,如果無效則從連接池中移除,并嘗試獲取繼續(xù)獲取
testOnBorrow ?//默認false,borrow的時候檢測是有有效,如果無效則從連接池中移除,并嘗試獲取繼續(xù)獲取
testOnReturn ?//默認false,return的時候檢測是有有效,如果無效則從連接池中移除,并嘗試獲取繼續(xù)獲取
testWhileIdle ?//默認false,在evictor線程里頭,當evictionPolicy.evict方法返回false時,而且testWhileIdle為true的時候則檢測是否有效,如果無效則移除

檢測參數(shù)
timeBetweenEvictionRunsMillis ?//空閑鏈接檢測線程檢測的周期,毫秒數(shù)。如果為負值,表示不運行檢測線程。默認為-1.
numTestsPerEvictionRun ?//在每次空閑連接回收器線程(如果有)運行時檢查的連接數(shù)量,默認為3
minEvictableIdleTimeMillis ?//連接空閑的最小時間,達到此值后空閑連接將可能會被移除。默認為1000L 60L 30L
softMinEvictableIdleTimeMillis ?//連接空閑的最小時間,達到此值后空閑鏈接將會被移除,且保留minIdle個空閑連接數(shù)。默認為-1.
evictionPolicyClassName ?//evict策略的類名,默認為org.apache.commons.pool2.impl.DefaultEvictionPolicy

其他
jmxEnabled ?//是否開啟jmx監(jiān)控,如果應(yīng)用開啟了jmx端口并且jmxEnabled設(shè)置為true,就可以通過jconsole或者jvisualvm看到關(guān)于連接池的相關(guān)統(tǒng)計,有助于了解連接池的使用情況,并且可以針對其做監(jiān)控統(tǒng)計,默認是true。
evictionPolicyClassName ?//設(shè)置的逐出策略類名, 默認"org.apache.commons.pool2.impl.DefaultEvictionPolicy"(當連接超過最大空閑時間,或連接數(shù)超過最大空閑連接數(shù))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評論 19 139
  • 我們在服務(wù)器開發(fā)的過程中,往往會有一些對象,它的創(chuàng)建和初始化需要的時間比較長,比如數(shù)據(jù)庫連接,網(wǎng)絡(luò)IO,大數(shù)據(jù)對象...
    王廣帥閱讀 5,813評論 1 4
  • 1 Redis介紹1.1 什么是NoSql為了解決高并發(fā)、高可擴展、高可用、大數(shù)據(jù)存儲問題而產(chǎn)生的數(shù)據(jù)庫解決方...
    克魯?shù)吕?/span>閱讀 5,714評論 0 36
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 30,215評論 8 265
  • “師叔,這么多竹架子,這么多燈,是要做什么用?”道士李青正在收拾簽文,聞言抬頭看向街巷當中。每隔二三丈置一燈架,從...
    遠航員阿花閱讀 612評論 0 0

友情鏈接更多精彩內(nèi)容