為什么要用Jedis連接池+淺談jedis連接池使用


為什么要使用Jedis連接池

Redis作為緩存數據庫理論上和MySQL一樣需要客戶端和服務端建立起來連接進行相關操作,使用MySQL的時候相信大家都會使用一款開源的連接池,例如C3P0.因為直連會消耗大量的數據庫資源,每一次新建一個連接之,使用后再斷開連接,對於頻繁訪問的場景,這顯然不是高效的。

Jedis連接池的使用

Jedis直連Redis

生產環境一般使用連接池的方式對Redis連接進行管理,所有Jedis對象先放在池子中每一次需要的時候連接Redis,只需要在池子中借,用完了再歸還給池子。

Jedis連接池的使用

Jedis連接池使用方式

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

Jedis連接池的使用

Jedis直連方式和連接池方式對比

Jedis提供了JedisPool這個類作為對Jedis的連接池。使用如下:
 1 public class RedisPool {
 2     //聲明成static的原因:保證jedis連接池在tomcat啟動時就加載出來
 3     //jedis連接池
 4     private static JedisPool pool;
 5     //與redis連接池連接的最大連接數
 6     private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total", "20"));
 7     //在這個連接池中最多有多少個狀態為idle的jedis實例,jedis連接池里就是jedis的實例,idle就是空閑的jedis實例
 8     //在jedis連接池中最大的idle狀態(空閑的)的jedis實例的個數
 9     private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle", "10"));
10     //在jedis連接池中最小的idle狀態(空閑的)的jedis實例的個數
11     private static Integer minIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle", "2"));
12 
13     //在borrow一個jedis實例的時候,是否要進行驗證操作,如果賦值為true,則得到的jedis實例肯定是可用的
14     private static Boolean testOnBorrow = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow", "true"));
15     //在return一個jedis實例的時候,是否要進行驗證操作,如果賦值為true,則返回jedis連接池的jedis實例肯定是可用的
16     private static Boolean testOnReturn = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return", "true"));
17 
18     private static String redisIp = PropertiesUtil.getProperty("redis.ip");
19     private static Integer redisPort = Integer.parseInt(PropertiesUtil.getProperty("redis.port"));
20 
21     //初始化連接池,只會調用一次
22     private static void initPool() {
23         JedisPoolConfig config = new JedisPoolConfig();
24 
25         config.setMaxTotal(maxTotal);
26         config.setMaxIdle(maxIdle);
27         config.setMinIdle(minIdle);
28 
29         config.setTestOnBorrow(testOnBorrow);
30         config.setTestOnReturn(testOnReturn);
31 
32         //連接池耗盡的時候,是否阻塞,false會拋出異常,true阻塞直到超時,會拋出超時異常,默認為true
33         config.setBlockWhenExhausted(true);
34 
35         //這里超時時間是2s
36         pool = new JedisPool(config, redisIp, redisPort, 1000*2);
37 
38     }
39 
40     static {
41         initPool();
42     }
43 
44     //從連接池中拿取一個實例
45     public static Jedis getJedis() {
46         return pool.getResource();
47     }
48 
49     //將正常實例放回jedis連接池
50     public static void returnResource(Jedis jedis) {
51         pool.returnResource(jedis);
52     }
53 
54     //將破損實例放回jedis連接池
55     public static void returnBrokenResource(Jedis jedis) {
56         pool.returnResource(jedis);
57     }
58 
59 }
View Code

JedisPoolUtil向外提供的工具類如下所示:

 

 1 public class RedisPoolUtil {
 2 
 3     //重新設置有效期
 4     //參數只有key和有效期,因為只需要根據key設置有效期即可
 5     public static Long expire(String key, int exTime) {
 6         Jedis jedis = null;
 7         Long result = null;
 8         try {
 9             jedis = RedisPool.getJedis();
10             //設置有效期
11             result = jedis.expire(key, exTime);
12         } catch (Exception e) {
13             log.error("setex key:{} error", key, e);
14             RedisPool.returnBrokenResource(jedis);
15             return result;
16         }
17         RedisPool.returnResource(jedis);
18         return result;
19     }
20 
21     //exTime單位是s,設置session有效時間
22     //當用戶初次登錄的時候,需要設置有限期,存在redis session中
23     //后續如果用戶再次請求登錄,則只需要調用expire,重新設置有效期即可
24     public static String setEx(String key, String value, int exTime) {
25         Jedis jedis = null;
26         String result = null;
27         try {
28             jedis = RedisPool.getJedis();
29             result = jedis.setex(key, exTime, value);
30         } catch (Exception e) {
31             log.error("setex key:{} value:{} error", key, value, e);
32             RedisPool.returnBrokenResource(jedis);
33             return result;
34         }
35         RedisPool.returnResource(jedis);
36         return result;
37     }
38 
39     public static String set(String key, String value) {
40         Jedis jedis = null;
41         //jedis返回的結果
42         String result = null;
43         try {
44             jedis = RedisPool.getJedis();
45             //設置key-value
46             result = jedis.set(key, value);
47         } catch (Exception e) {
48             log.error("set key:{} value:{} error", key, value, e);
49             RedisPool.returnBrokenResource(jedis);
50             return result;
51         }
52         RedisPool.returnResource(jedis);
53         return result;
54     }
55 
56     public static String get(String key) {
57         Jedis jedis = null;
58         String result = null;
59         try {
60             jedis = RedisPool.getJedis();
61             //根據key獲取value值
62             result = jedis.get(key);
63         } catch (Exception e) {
64             log.error("set key:{} error", key, e);
65             RedisPool.returnBrokenResource(jedis);
66             return result;
67         }
68         RedisPool.returnResource(jedis);
69         return result;
70     }
71 
72     public static Long del(String key) {
73         Jedis jedis = null;
74         Long result = null;
75         try {
76             jedis = RedisPool.getJedis();
77             //根據key刪除key-value
78             result = jedis.del(key);
79         } catch (Exception e) {
80             log.error("set key:{} error", key, e);
81             RedisPool.returnBrokenResource(jedis);
82             return result;
83         }
84         RedisPool.returnResource(jedis);
85         return result;
86     }
87 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM