java操作redis(三):實現一個redis連線池並附測試
阿新 • • 發佈:2019-02-20
環境:jdk1.7 redis3.2.8
所需jar包:jedis-2.9.0.jar commons-pool2-2.3
Jedis連線池使用步驟如下:
1->獲取Jedis例項需要從JedisPool中獲取;
2->用完Jedis例項需要返還給JedisPool;
3->如果Jedis在使用過程中出錯,則也需要還給JedisPool;
=================連線池引數配置檔案redis.properties================
=================Redis連線池工具類RedisPoolUtil================#*****************jedis連線引數設定********************* #redis伺服器ip redis.ip=169.254.130.122 #redis伺服器埠號 redis.port=6379 #redis訪問密碼 redis.passWord=test123 #與伺服器建立連線的超時時間 redis.timeout=3000 #************************jedis池引數設定******************* #jedis的最大活躍連線數 jedis.pool.maxActive=100 #jedis最大空閒連線數 jedis.pool.maxIdle=50 #jedis池沒有連線物件返回時,等待可用連線的最大時間,單位毫秒,預設值為-1,表示永不超時。 #如果超過等待時間,則直接丟擲JedisConnectionException jedis.pool.maxWait=1500 #從池中獲取連線的時候,是否進行有效檢查 jedis.pool.testOnBorrow=true #歸還連線的時候,是否進行有效檢查 jedis.pool.testOnReturn=true
package com.wx.utils; import java.util.Properties; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * Redis連線池工具類 */ public class RedisPoolUtil { private static JedisPool jedisPool = null; private static String redisConfigFile = "redis.properties"; //把redis連線物件放到本地執行緒中 private static ThreadLocal<Jedis> local=new ThreadLocal<Jedis>(); //不允許通過new建立該類的例項 private RedisPoolUtil() { } /** * 初始化Redis連線池 */ public static void initialPool() { try { Properties props = new Properties(); //載入連線池配置檔案 props.load(RedisPoolUtil.class.getClassLoader().getResourceAsStream(redisConfigFile)); // 建立jedis池配置例項 JedisPoolConfig config = new JedisPoolConfig(); // 設定池配置項值 config.setMaxTotal(Integer.valueOf(props.getProperty("jedis.pool.maxActive"))); config.setMaxIdle(Integer.valueOf(props.getProperty("jedis.pool.maxIdle"))); config.setMaxWaitMillis(Long.valueOf(props.getProperty("jedis.pool.maxWait"))); config.setTestOnBorrow(Boolean.valueOf(props.getProperty("jedis.pool.testOnBorrow"))); config.setTestOnReturn(Boolean.valueOf(props.getProperty("jedis.pool.testOnReturn"))); // 根據配置例項化jedis池 jedisPool = new JedisPool(config, props.getProperty("redis.ip"), Integer.valueOf(props.getProperty("redis.port")), Integer.valueOf(props.getProperty("redis.timeout")), props.getProperty("redis.passWord")); System.out.println("執行緒池被成功初始化"); } catch (Exception e) { e.printStackTrace(); } } /** * 獲得連線 * @return Jedis */ public static Jedis getConn() { //Redis物件 Jedis jedis =local.get(); if(jedis==null){ if (jedisPool == null) { initialPool(); } jedis = jedisPool.getResource(); local.set(jedis); } return jedis; } //新版本用close歸還連線 public static void closeConn(){ //從本地執行緒中獲取 Jedis jedis =local.get(); if(jedis!=null){ jedis.close(); } local.set(null); } //關閉池 public static void closePool(){ if(jedisPool!=null){ jedisPool.close(); } } }
============執行緒測試類============
執行過程中,去伺服器看連線數package com.wx.test; import java.text.SimpleDateFormat; import java.util.Date; import com.wx.utils.RedisPoolUtil; import redis.clients.jedis.Jedis; public class TestPool { public static void main(String[] args) { //初始化連線池 RedisPoolUtil.initialPool(); //啟動1000個執行緒 for (int i = 0; i < 1000; i++) { ClientThread t = new ClientThread(i); t.start(); } } } //執行緒類 class ClientThread extends Thread { int i = 0; public ClientThread(int i) { this.i = i; } public void run() { Jedis jedis=RedisPoolUtil.getConn(); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); String time = sdf.format(date); jedis.set("key"+i, time); try { //每次睡眠一個隨機時間 Thread.sleep((int)(Math.random()*5000)); String foo = jedis.get("key"+i); System.out.println("【輸出>>>>】key:" + foo + " 第:"+i+"個執行緒"); } catch (InterruptedException e) { e.printStackTrace(); }finally { RedisPoolUtil.closeConn(); } } }
127.0.0.1:6379> info clients
# Clients
connected_clients:102
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379> info clients
# Clients
connected_clients:70
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379> info clients
# Clients
connected_clients:53
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379> info clients
# Clients
connected_clients:2
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379> info clients
# Clients
connected_clients:2
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
127.0.0.1:6379>
可以看出連線池中最大100個活躍連線迅速被佔滿,(最開始102個是因為我單獨啟動了兩個連線)
然後連線用完了,迅速歸還連線
java端的執行結果
可以看出有超時沒拿到連線的報錯!
ok,測試成功!