異常最も奇妙な第2期のJedis pool.returnResource(jedis)

10798 ワード

誰の問題だ?


commons-collections-3.2.jar

# 1 Exception in thread "main"java.lang.NoClassDefFoundError: org/apache/commons/collections/CursorableLinkedList


分析:RedisのJava APIでJedisが間違っていて、これを見てあなたはきっとこの問題が少し低級だと思って、確かに低級で、見なくてもjarパッケージを少なく導いたことを知っていますが、これは重点ではありません.重点はJedisの中の1つの方法です:pool.returnResource(jedis);これこそ重点の中の重点で、次にこの方法の説明を見てみましょう:voidredis.clients.util.Pool.returnResource(Jedis jedis)はこの中に異常な声明のサブクラスが投げ出されていないことを見ることができて、それでは私達はtry-catchに行くことはできなくて、try-catchに行かない結果はわけのわからない間違いが現れて、try-catchはjavaが現れます.lang.Null PointerExceptioのような空のポインタが異常で、このような情報は私たちに役に立たない.これはjarパッケージが欠けていることによる問題だが、ここではjavaを提示する.lang.Null PointerExceptionのような空のポインタが異常で、これは穴のお父さんではありませんか?(まったく私たちが欲しいものではありません)、、、それからお父さんに穴をあけ始めました.自分で間違いを探し始めました.運が悪いとN久を探しても見つかりません.パソコンを壊す衝動があります.運が良ければすぐに間違いを見つけます.次のコードを見てください.try-catchとtry-catchを使うのとの比較をしないでください.空腹の時はtry-catchを使わなかった.この方法だからだ.returnResource(jedis);異常放出が宣言されていないので、自然に使えません.(坑お父さん!)
原因:commons-collections-3.2が欠けているjarのようなjarパッケージ
解決:commons-collections-3.2をインポートする.jarこのjarパッケージでいいです
 
#try-catchを使用していないコードに対応する異常情報

#try-catchを使用していないコード


publicvoid hdel(String key, String field){
       JedisPoolpool =null;
       Jedisjedis =null;
       try {
           pool= getJedisPool(key);
           jedis= pool.getResource();
           jedis.hdel(key,field);
       }catch (Exception e) {
           log.error("Redis hdel exception :" + key, e);
           pool.returnBrokenResource(jedis);
       }finally {
              pool.returnResource(jedis);
       }

#異常情報


java.lang.NullPointerException
         atcn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils.hset(ConsistentHashRedisUtils.java:164)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorStoreRedis.userBehavior2Redis(UserBehaviorStoreRedis.java:58)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorAnalysisMainClass.main(UserBehaviorAnalysisMainClass.java:33)

#try-catchを使用したコード


public void hdel(String key, String field) {
       JedisPool pool =null;
       Jedis jedis =null;
       try {
           pool = getJedisPool(key);
           jedis = pool.getResource();
           jedis.hdel(key, field);
       } catch (Exception e) {
           log.error("Redis hdel exception : "+key, e);
           pool.returnBrokenResource(jedis);
       } finally {
           try {
              pool.returnResource(jedis);
           }catch(Exception e) {
             log.error("JdisreturnResource exception : ", e);
           }
       }

#異常情報


[2014-07-1016:39:17,659].[ERROR].[cn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils]
    JdisreturnResource exception :
 
java.lang.NullPointerException
         atcn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils.hset(ConsistentHashRedisUtils.java:164)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorStoreRedis.userBehavior2Redis(UserBehaviorStoreRedis.java:58)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorAnalysisMainClass.main(UserBehaviorAnalysisMainClass.java:33)
Exception in thread"main"java.lang.NoClassDefFoundError:org/apache/commons/collections/CursorableLinkedList
         atorg.apache.commons.pool.impl.GenericObjectPool.(GenericObjectPool.java:392)
         atorg.apache.commons.pool.impl.GenericObjectPool.(GenericObjectPool.java:275)
         atredis.clients.util.Pool.(Pool.java:14)
         atredis.clients.jedis.JedisPool.(JedisPool.java:24)
         atredis.clients.jedis.JedisPool.(JedisPool.java:29)
         atcn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils.getJedisPool(ConsistentHashRedisUtils.java:343)
         atcn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils.getJedisPool(ConsistentHashRedisUtils.java:317)
         atcn.adsit.iva.preroll.dp.synch.analysis.redis.util.ConsistentHashRedisUtils.hset(ConsistentHashRedisUtils.java:156)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorStoreRedis.userBehavior2Redis(UserBehaviorStoreRedis.java:58)
         atcn.adsit.iva.preroll.dp.synch.analysis.UserBehaviorAnalysisMainClass.main(UserBehaviorAnalysisMainClass.java:33)
Caused by:java.lang.ClassNotFoundException:org.apache.commons.collections.CursorableLinkedList
         atjava.net.URLClassLoader$1.run(URLClassLoader.java:217)
         atjava.security.AccessController.doPrivileged(Native Method)
 
         atjava.net.URLClassLoader.findClass(URLClassLoader.java:205)
         atjava.lang.ClassLoader.loadClass(ClassLoader.java:319)
         atjava.lang.ClassLoader.loadClass(ClassLoader.java:264)
         atjava.lang.ClassLoader.loadClassInternal(ClassLoader.java:332)
         ... 10more
 
    }

#まとめ1


比較すると、try-catchを使用すると、元は見えなかったより重要な異常情報を見ることができる:Caused by:java.lang.ClassNotFoundException:org.apache.commons.collections.CursorableLinkedList
を選択し、commons-collections-3.2をインポートすることを知っています.jarのようなjarバッグは、それから完成して、説明しないで、1つの穴のお父さんの問題、jarバッグが欠けて、自分が不注意だと言ってもいいでしょう.
こんな問題にも遭遇した友人、、、
public void testGet() {  
        Jedis jedis = null;   
        try {  
            //        jedis    
            jedis = jedisPool.getResource();  
            System.out.println(jedis.get("blog_pool"));  
        } catch (Exception e) {  
            //       
            jedisPool.returnBrokenResource(jedis);  
            Assert.fail(e.getMessage());  
        } finally {  
            //         
            jedisPool.returnResource(jedis);  
        }  
    }  
package com.ljq.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**   
 * Redis    
 *
 * @author    
 * @version 1.0 2013-6-14   08:54:14   
 */
public class RedisAPI {
    private static JedisPool pool = null;
    
    /**
     *   redis   
     * 
     * @param ip
     * @param port
     * @return JedisPool
     */
    public static JedisPool getPool() {
        if (pool == null) {
            JedisPoolConfig config = new JedisPoolConfig();
            //    pool      jedis  ,  pool.getResource()   ;
            //     -1,      ;  pool     maxActive jedis  ,   pool    exhausted(  )。
            config.setMaxActive(500);
            //    pool         idle(   ) jedis  。
            config.setMaxIdle(5);
            //   borrow(  )  jedis   ,       ,        ,     JedisConnectionException;
            config.setMaxWait(1000 * 100);
            // borrow  jedis   ,      validate  ;   true,    jedis       ;
            config.setTestOnBorrow(true);
            pool = new JedisPool(config, "192.168.2.191", 8888);
        }
        return pool;
    }
    
    /**
     *       
     * 
     * @param pool 
     * @param redis
     */
    public static void returnResource(JedisPool pool, Jedis redis) {
        if (redis != null) {
            pool.returnResource(redis);
        }
    }
    
    /**
     *     
     * 
     * @param key
     * @return
     */
    public static String get(String key){
        String value = null;
        
        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //  redis  
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //      
            returnResource(pool, jedis);
        }
        
        return value;
    }
}

コード説明:a、jedisインスタンスを取得する場合、実際には2つのエラーが発生する可能性があります.一つはpoolです.getResource()は、使用可能なjedisインスタンスが得られません.もう一つはjedisですset/getでエラーが発生しても異常が放出されます.区分を実現するために、instanceがnullであるかどうかによって実現され、空であればinstanceが初期化されていないことを証明し、poolにreturnを与える必要はありません.instanceがnullでない場合、poolに返却する必要があることを証明します.
b、instanceエラーの場合、returnBrokenResourceを呼び出してpoolに返却する必要があります.そうしないと、次回getResourceで得られるinstanceのバッファにデータが存在し、問題が発生する可能性があります.
-------------------------------------------------
JedisPoolの構成パラメータは実際の応用ニーズ、ソフト・ハードウェア能力に大きく依存している.以前はcommons-poolを使ったことがないので、今回は一日中これらのパラメータの意味を見ていました.のJedisPoolの構成パラメータの大部分はJedisPoolConfigの対応する項によって与えられる.
maxActive:poolに割り当てられるjedisインスタンスの数を制御し、pool.getResource()を取得します.付与値が-1の場合、制限はありません.poolがmaxActive個jedisインスタンスを割り当てた場合、poolの状態はexhaustedになります.
maxIdle:poolがidle(アイドル)のjedisインスタンスを最大数個制御します.
whenExhaustedAction:poolのjedisインスタンスがallocatedで完了した場合、poolが取る操作を示します.デフォルトは3種類あります.WHEN_EXHAUSTED_FAIL-->jedisインスタンスがない場合は、NoSuchElementExceptionを直接放出します.WHEN_EXHAUSTED_BLOCK-->は、ブロックされているか、maxWaitに達したときにJedisConnectionExceptionを放出していることを示します.WHEN_EXHAUSTED_GROW-->はjedisインスタンスを新規作成することを表し、つまり設定したmaxActiveが役に立たないことを表す.
maxWait:borrowのjedisインスタンスの場合、最大の待機時間を表し、待機時間を超えた場合、JedisConnectionExceptionを直接投げ出す.
testOnBorrow:borrowのjedisインスタンスの場合、alidate操作を事前に行うかどうか.trueの場合、得られたjedisインスタンスはいずれも使用可能である.
testOnReturn:returnがpoolに与えられた場合、validate操作を事前に行うかどうか.
testWhileIdle:trueの場合、idle object evitorスレッドがidle objectをスキャンし、validateが失敗するとpoolからdropされます.これはtimeBetweenEveictionRunsMillisが0より大きい場合にのみ意味がある.
timeBetweenEveictionRunsMillis:idle object evitorの2回のスキャンの間にsleepが必要なミリ秒数を示します.
numTestsPerEveictionRun:idle object evitorがスキャンするたびに最も多くのオブジェクト数を表します.
minEveictableIdleTimeMillis:1つのオブジェクトがidle状態の最短時間にとどまることを示し、idle object evitorにスキャンされて駆逐される.これはtimeBetweenEveictionRunsMillisが0より大きい場合にのみ意味がある.
softMinEveictableIdleTimeMillis:minEveictableIdleTimeMillisに加えて、少なくともminIdle個のオブジェクトがpoolに入っています.-1の場合、evictedはidle timeに基づいてオブジェクトを駆逐しません.m i n v e v i c tableIdleTimeMillis>0の場合、この設定は意味がなく、timeBetweenEveictionRunsMillisが0より大きい場合にのみ意味があります.
lifo:borrowObjectがオブジェクトを返す場合、DEFAULT_を使用します.LIFO(last in first out、すなわちcacheのような最も頻繁に使用されるキュー)は、FalseであればFIFOキューを表す.
ここで、JedisPoolConfigのパラメータのデフォルト設定は、testWhileIdle=true m i n v i c tableIdleTimeMills=60000 timeBetweenEvenictionRunsMillis=30000 numTestsPerEveictionRun=-1です.