redis常見JedisConnectionException異常分析_第1頁
redis常見JedisConnectionException異常分析_第2頁
redis常見JedisConnectionException異常分析_第3頁
redis常見JedisConnectionException異常分析_第4頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

【redis】常見JedisConnectionException異常分析最近項目開發(fā)中用到了Redis,選擇了官網推薦的javaclientJedis。

Redis常用命令學習:http://redis.io/commands

Redis官方推薦Java客戶端Jedis(包含了所有Redis命令的實現(xiàn)):/xetorthio/jedis

Jedis使用過程中最常見異常JedisConnectionException有時確實給我們帶來了很多困惑,這個異常通常出現(xiàn)在兩個使場景。

一、當我們執(zhí)行如下JedisPool類實例的getResource()時拋出can'tgetaresource異常。異常代碼如下:redis.clients.jedis.exceptions.JedisConnectionException:Couldnotgetaresourcefromthepoolatredis.clients.util.Pool.getResource(Pool.java:22)分析:redis.clients.util.Pool.getResource會從JedisPool實例池中返回一個可用的redis連接。分析源碼可知JedisPoolextendsredis.clients.util.Pool<Jedis>

.而Pool<T>是通過commons-pool開源工具包中的mons.pool.impl.GenericObjectPool來實現(xiàn)對Jedis實例的管理的。所以我們分析一下GenericObjectPool或許能找到答案。首先看一下common-pool的api:/pool/apidocs/index.html?org/apache/commons/pool/impl/GenericObjectPool.html。

其中三個重要個幾個屬性是:

MaxActive:可用連接實例的最大數(shù)目,為負值時沒有限制。

MaxIdle:空閑連接實例的最大數(shù)目,為負值時沒有限制。Idle的實例在使用前,通常會通過mons.pool.BasePoolableObjectFactory<T>的activateObject()方法使其變得可用。

MaxWait:等待可用連接的最大數(shù)目,單位毫秒(millionseconds)。

(注:pool.getResource()方法實際調用的GenericObjectPool類borrowObject()方法,該方法會根據MaxWait變量值在沒有可用連接(idle/active)時阻塞等待知道超時,具體含義參看api。)也就是說當連接池中沒有active/idle的連接時,會等待maxWait時間,如果等待超時還沒有可用連接,則拋出Couldnotgetaresourcefromthepool異常。所以為避免這樣的錯誤,我們應該根據程序實際情況合理設置這三個參數(shù)的值,同時在我們獲取一個連接的程序方法中也應該合理的處理這個異常,當沒有連接可用時,等待一段時間再獲取也許是個比較好的選擇。二、當我們獲取連接后對redis進行操作時,拋出redis.clients.jedis.exceptions.JedisConnectionException:.SocketTimeoutException:Readtimedout異常。異常代碼如下:redis.clients.jedis.exceptions.JedisConnectionException:.SocketTimeoutException:Readtimedoutatredis.clients.jedis.Pcess(Protocol.java:79)

atredis.clients.jedis.Protocol.read(Protocol.java:131)

atredis.clients.jedis.Connection.getIntegerReply(Connection.java:188)

atredis.clients.jedis.Jedis.sismember(Jedis.java:1266)這是一個比較麻煩的異常,困擾了我一天的時間。我們都知道Redis是對內存進行操作,速度應該都在毫秒級,這是我們通常的認識,所以當對Redis操作出現(xiàn)幾秒的超時時間,你能想象嗎?

我們還是先分析一下Jedis的源代碼吧,以sadd操作為例:publicLongsadd(finalStringkey,finalString...members){checkIsInMulti();client.sadd(key,members);returnclient.getIntegerReply();}client是redis.clients.jedis.Client.java的實例,繼承關系如下:

publicclassClientextendsBinaryClientimplementsCommands;publicclassBinaryClientextendsConnection;Connection包裝了對Redisserver的socket操作,命令寫操作通過socket.getOutputStream()輸出流將命令信息發(fā)送到redisserver,當寫完命令后要通過socket.getInputStream()的到的輸入流將

命令執(zhí)行結果返回,這中間必然會有一個命令執(zhí)行到結果返回的延時時間,這就是一個Jedis調用redis命令操作所用的時間。需要說明的是,Redisserver是單線程執(zhí)行所有連接發(fā)送過來的命令的,也就是說不管并發(fā)中有多少個client在發(fā)送命令,redis-server端是單線程處理的,并按照默認的FIFO方式處理請求,這個可在redis.conf配置文件中配置。關于redisserver的詳細運行機制參見:http://redis.io/documentation所以client.sadd(key,members);調用完后只是將命令信息發(fā)送到了redisserver端,具體有沒有執(zhí)行要看redisserver的負載情況。然后,通過client.getIntegerReply();等待(timeout)返回結果。

Connection初始化socket時有多種選擇,其中設置sockettimeout的方法如下:publicvoidrollbackTimeout(){

try{

socket.setSoTimeout(timeout);

socket.setKeepAlive(false);

}catch(SocketExceptionex){

thrownewJedisException(ex);

}

}由redis.clients.jedis.Protocol.DEFAULT_TIMEOUT=2000我們知道默認的超時時間是2秒,這個時間相對于redis操作內存毫秒級的速度來說已經很長,那我們?yōu)槭裁催€會遇到

.SocketTimeoutException:Readtimedout異常呢?redis操作內存雖然平均毫秒級的,但當數(shù)據量很大時未必都如此快速。在我的開發(fā)過程中就遇到過一個集合到了千萬級數(shù)據量,一次操作超時時間在秒級是很正常的,而且機器性能很好的情況下已經如此,更何況我們本機開發(fā)的機器相對于生產服務器來說速度會更慢了。所以在初始化JedisPool時應該根據實際情況通過redis.clients.jedis.JedisPoolConfig合理設置連接池參數(shù),通過edisPool構造方法,合理設置s

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論