徹底解決 Jedis 連接池 獲取不到連接,連接放回連接池錯誤的問題

public class CacheKit {
    private static Logger logger = LoggerFactory.getLogger(CacheKit.class);
    private List<JSONObject> resultList;
    private static JedisPool pool;

    /**
     * 初始化Redis連接池
     */
    private static void initializePool() {
		//redisURL 與 redisPort 的配置文件
        String configFile = "production.properties";
        if (PropKit.getBoolean("devMode")) {
            configFile = "dev.properties";
        }

        JedisPoolConfig config = new JedisPoolConfig();
		//設置最大連接數(100個足夠用了,沒必要設置太大)
		config.setMaxTotal(100);
		//最大空閒連接數
		config.setMaxIdle(10);
		//獲取Jedis連接的最大等待時間(50秒) 
		config.setMaxWaitMillis(50 * 1000);
		//在獲取Jedis連接時,自動檢驗連接是否可用
		config.setTestOnBorrow(true);
		//在將連接放回池中前,自動檢驗連接是否有效
		config.setTestOnReturn(true);
		//自動測試池中的空閒連接是否都是可用連接
		config.setTestWhileIdle(true);
		//創建連接池
		pool = new JedisPool(config, PropKit.use(configFile).get("redisURL"),
					PropKit.use(configFile).getInt("redisPort"));
    }

    /**
     * 多線程環境同步初始化(保證項目中有且僅有一個連接池)
     */
    private static synchronized void poolInit() {
        if (null == pool) {
            initializePool();
        }
    }

    /**
     * 獲取Jedis實例
     */
    private static Jedis getJedis() {
        if (null == pool) {
            poolInit();
        }

        int timeoutCount = 0;
        while (true) {
            try {
                if (null != pool) {
                    return pool.getResource();
                }
            } catch (Exception e) {
                if (e instanceof JedisConnectionException) {
                    timeoutCount++;
                    logger.warn("getJedis timeoutCount={}", timeoutCount);
                    if (timeoutCount > 3) {
                        break;
                    }
                } else {
                    logger.warn("jedisInfo ... NumActive=" + pool.getNumActive()
                            + ", NumIdle=" + pool.getNumIdle()
                            + ", NumWaiters=" + pool.getNumWaiters()
                            + ", isClosed=" + pool.isClosed());
                    logger.error("GetJedis error,", e);
                    break;
                }
            }
            break;
        }
        return null;
    }

    /**
     * 釋放Jedis資源
     *
     * @param jedis
     */
    public static void returnResource(Jedis jedis) {
        if (null != jedis) {
            pool.returnResourceObject(jedis);
        }
    }

    /**
     * 絕對獲取方法(保證一定能夠使用可用的連接獲取到 目標數據)
     * Jedis連接使用後放回 
     * @param key
     * @return
     */
    private String safeGet(String key) {
        Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        String value = jedis.get(key);
        returnResource(jedis);
        return value;
    }

    /**
     * 絕對設置方法(保證一定能夠使用可用的鏈接設置 數據)
     * Jedis連接使用後返回連接池
     * @param key
     * @param time
     * @param value
     */
    private void safeSet(String key, int time, String value) {
        Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        jedis.setex(key, time, value);
        returnResource(jedis);
    }

    /**
     * 絕對刪除方法(保證刪除絕對有效)
     * Jedis連接使用後返回連接池</span>
     * @param key
     */
    private void safeDel(String key) {
        Jedis jedis = getJedis();
        while (true) {
            if (null != jedis) {
                break;
            } else {
                jedis = getJedis();
            }
        }
        jedis.del(key);
        returnResource(jedis);
    }

    /**自定義的一些 get set del 方法,方便使用**/
    public JSONObject getByCache(String key) {
        String result = safeGet(key);
        if (result != null) {
            return (JSONObject) JSONObject.parse(result);
        }
        return null;

    }

    public String getByCacheToString(String key) {
        String result = safeGet(key);
        if (result != null) {
            return result;
        }
        return null;

    }

    public List<JSONObject> getArrayByCache(String key) {
        String result = safeGet(key);
        if (result != null) {
            resultList = JSONArray.parseArray(result, JSONObject.class);
            return resultList;
        }
        return null;
    }

    public JSONArray getJSONArrayByCache(String key) {
        String result = safeGet(key);
        if (result != null) {
            return JSONArray.parseArray(result);
        }
        return null;
    }

    public void setByCache(String key, String s) {
        safeSet(key, 86400, s);
    }

    public void setByCacheOneHour(String key, String s) {
        safeSet(key, 3600, s);
    }

    public void setByCacheOneHour(String key, List<JSONObject> json) {
        safeSet(key, 86400, JSONObject.toJSONString(json));
        resultList = json;
    }

    public void setByCache(String key, JSONObject json) {
        safeSet(key, 86400, JSONObject.toJSONString(json));
    }

    public void setByCache(String key, List<JSONObject> list) {
        safeSet(key, 86400, JSONObject.toJSONString(list));
        resultList = list;
    }

    public void setByCache(String key, JSONArray array) {
        safeSet(key, 86400, JSONArray.toJSONString(array));
    }

    public void setByCacheCusTime(String key, String s, int time) {
        safeSet(key, time, s);
    }


    public void delByCache(String key) {
        if (null != safeGet(key)) {
            safeDel(key);
        }
    }

    public JSONObject toJSON(DBObject db) {
        return (JSONObject) JSONObject.toJSON(db);
    }

    public List<JSONObject> toJSON(List<DBObject> list) {
        List<JSONObject> json = new ArrayList<>();
        for (DBObject aList : list) {
            json.add((JSONObject) JSONObject.toJSON(aList));
        }
        return json;
    }

    public boolean notNull() {
        return resultList != null && resultList.size() > 0;
    }

    public List<JSONObject> getResult() {
        return resultList;
    }

}


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