redis工具類-即拿即用

連接redis集羣:

package com.ssq.dmp.utils.jedis;

import redis.clients.jedis.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.logging.Logger;

/**
 * Jedis工具類
 */
public class JedisConnectionUtil {
    
    private final static Logger logger = Logger.getLogger(JedisPoolUtil.class.getName());
    /**
     * jedis哨兵集羣連接單例對象
     */
    private static JedisSentinelPool jedisSentinelPool = null;

    /**
     * jedis集羣連接單例對象
     */
    private static JedisCluster jedisCluster = null;

    private static Properties getJedisProperties() {
        Properties config = new Properties();
        InputStream is = null;
        try {
            is = JedisConnectionUtil.class.getClassLoader().getResourceAsStream("jedisConfig.properties");
            config.load(is);
        } catch (IOException e) {
            logger.info(e.getMessage());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    logger.info(e.getMessage());
                }
            }
        }
        return config;
    }
    /**
     * 創建JedisCluster
     * JedisCluster不需要單獨構建連接池,其已經基於連接池實現
     */
    private static void createJedisCluster(){
        //讀取配置文件
        Properties prop = getJedisProperties();
        //jedisCluster配置
        String[] serverArray = prop.getProperty("servers").split(",");
        int connectionTimeout = Integer.parseInt(prop.getProperty("connectionTimeout"));
        int soTimeout = Integer.parseInt(prop.getProperty("soTimeout"));
        int maxAttempts = Integer.parseInt(prop.getProperty("maxAttempts"));

        //jedis連接池配置
        // 建立連接池配置參數
        JedisPoolConfig config = new JedisPoolConfig();
        // 設置最大連接數
        config.setMaxTotal(new Integer(prop.getProperty("maxTotal")));
        // 設置最大阻塞時間,記住是毫秒數milliseconds
        config.setMaxWaitMillis(new Integer(prop.getProperty("maxWaitMillis")));
        // 設置最大空間連接數
        config.setMaxIdle(new Integer(prop.getProperty("maxIdle")));
        // 設置最小空間連接數
        config.setMinIdle(new Integer(prop.getProperty("minIdle")));
        // jedis實例是否可用
        boolean testOnBorrow = !prop.getProperty("testOnBorrow").equals("false");
        config.setTestOnBorrow(testOnBorrow);
        //#從連接池獲取不到連接則阻塞
        boolean blockWhenExhausted = !prop.getProperty("blockWhenExhausted").equals("false");
        config.setBlockWhenExhausted(blockWhenExhausted);
        //#連接對象後進先出
        boolean lifo = !prop.getProperty("lifo").equals("false");
        config.setLifo(lifo);
        //#歸還連接到池時測試連接
        boolean testOnReturn = !prop.getProperty("testOnReturn").equals("false");
        config.setTestOnReturn(testOnReturn);
        //#測試連接池空閒的連接
        boolean testWhileIdle = !prop.getProperty("testWhileIdle").equals("false");
        config.setTestWhileIdle(testWhileIdle);
        //#測試連接池空閒連接的時間間隔,testWhileIdle=true時生效
        config.setTimeBetweenEvictionRunsMillis(new Integer(prop.getProperty("timeBetweenEvictionRunsMillis")));

        Set<HostAndPort> nodes = new HashSet<>();

        for (String ipPort : serverArray) {
            String[] ipPortPair = ipPort.split(":");
            nodes.add(new HostAndPort(ipPortPair[0].trim(), Integer.parseInt(ipPortPair[1].trim())));
        }

        //注意:這裏超時時間不要太短,他會有超時重試機制
        jedisCluster = new JedisCluster(nodes, connectionTimeout, soTimeout, maxAttempts,config);
    }

    /**
     * 創建sentinel連接池
     */
    private static void createJedisSentinelPool(){
        //讀取jedis配置文件
        Properties prop = getJedisProperties();
        //jedis連接池配置
        // 建立連接池配置參數
        JedisPoolConfig config = new JedisPoolConfig();
        // 設置最大連接數
        config.setMaxTotal(new Integer(prop.getProperty("maxTotal")));
        // 設置最大阻塞時間,記住是毫秒數milliseconds
        config.setMaxWaitMillis(new Integer(prop.getProperty("maxWaitMillis")));
        // 設置最大空間連接數
        config.setMaxIdle(new Integer(prop.getProperty("maxIdle")));
        // 設置最小空間連接數
        config.setMinIdle(new Integer(prop.getProperty("minIdle")));
        // jedis實例是否可用
        boolean testOnBorrow = !prop.getProperty("testOnBorrow").equals("false");
        config.setTestOnBorrow(testOnBorrow);
        //#從連接池獲取不到連接則阻塞
        boolean blockWhenExhausted = !prop.getProperty("blockWhenExhausted").equals("false");
        config.setBlockWhenExhausted(blockWhenExhausted);
        //#連接對象後進先出
        boolean lifo = !prop.getProperty("lifo").equals("false");
        config.setLifo(lifo);
        //#歸還連接到池時測試連接
        boolean testOnReturn = !prop.getProperty("testOnReturn").equals("false");
        config.setTestOnReturn(testOnReturn);
        //#測試連接池空閒的連接
        boolean testWhileIdle = !prop.getProperty("testWhileIdle").equals("false");
        config.setTestWhileIdle(testWhileIdle);
        //#測試連接池空閒連接的時間間隔,testWhileIdle=true時生效
        config.setTimeBetweenEvictionRunsMillis(new Integer(prop.getProperty("timeBetweenEvictionRunsMillis")));
        //獲取redis密碼
        //String password = prop.getProperty("PASSWORD");
        String masterName = prop.getProperty("MASTER");
        String sentinel_1 = prop.getProperty("SENTINEL_1");
        String sentinel_2 = prop.getProperty("SENTINEL_2");
        String sentinel_3 = prop.getProperty("SENTINEL_3");
        Set<String> sentinels = new HashSet<>();
        sentinels.add(sentinel_1);
        sentinels.add(sentinel_2);
        sentinels.add(sentinel_3);
        jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config);
    }

    /**
     * 在多線程環境同步初始化
     */
    private static synchronized void JedisClusterInit(){
        if (jedisCluster == null)
          createJedisCluster();
    }

    /**
     * 在多線程環境同步初始化
     */
    private static synchronized void sentinelPoolInit(){
        if (jedisSentinelPool == null)
            createJedisSentinelPool();
    }

    /**
     * 獲取一個jedis對象
     * @return
     */
    public static Jedis getJedis(){
        if (jedisSentinelPool == null)
            sentinelPoolInit();
        Jedis resource = jedisSentinelPool.getResource();
//        resource.auth("123");
        return resource;
    }

    /**
     * 獲取一個jedis對象
     * @return
     */
    public static JedisCluster getJedisCluster(){
        if (jedisCluster == null)
            JedisClusterInit();
        return jedisCluster;
    }

    /**
     * 釋放一個連接
     * @param jedis
     */
    public static void returnRes(Jedis jedis){
        jedisSentinelPool.returnResource(jedis);
    }

    /**
     * 銷燬一個連接
     * @param jedis
     */
    public static void returnBrokenRes(Jedis jedis){
        jedisSentinelPool.returnBrokenResource(jedis);
    }

    /**
     * 獲取集羣上所有key
     * @param pattern
     * @return
     */
    public static TreeSet<String> keys(JedisCluster jc, String pattern){
        TreeSet<String> keys = new TreeSet<>();
        Map<String, JedisPool> clusterNodes = jc.getClusterNodes();
        for(String k : clusterNodes.keySet()){
            JedisPool jp = clusterNodes.get(k);
            Jedis jedis = jp.getResource();
            try {
                keys.addAll(jedis.keys(pattern));
            } catch(Exception e){
                e.printStackTrace();
            } finally{
                //用完一定要close這個鏈接!!!
                jedis.close();
            }
        }
        return keys;
    }

    /**
     * 連接redis方法
     * @param args
     */
    public static void main(String[] args) throws IOException {
        JedisCluster jedisCluster=getJedisCluster();
      /*  jedisCluster.set("sjk", "hello");
        jedisCluster.set("BlackChangeFlag", "false");
        jedisCluster.set("ProcessChangeFlag", "false");
        jedisCluster.set("FilterChangeFlag", "false");
        jedisCluster.set("wh", "hello");
        jedisCluster.set("lxy", "hello");
        jedisCluster.set("pyx", "hello");*/
        //System.out.println("sjk============" + jedisCluster.get("sjk"));

        TreeSet<String> keySets = keys(jedisCluster, "CSANTI_MONITOR_DP*");
        //使用完成後不要調用close,將會導致無法繼續使用該對象
        //jedisCluster.close();
        for(String k: keySets){
            System.out.println(k + " ============ " + jedisCluster.get(k));
        }
        TreeSet<String> keySets1 = keys(jedisCluster, "CSANTI_MONITOR_QUERY*");
        //使用完成後不要調用close,將會導致無法繼續使用該對象
        //jedisCluster.close();
        for(String k: keySets1){
            System.out.println(k + " ------------------ " + jedisCluster.get(k));
        }
        TreeSet<String> keySets2 = keys(jedisCluster, "CSANTI_MONITOR_BOOK*");
        //使用完成後不要調用close,將會導致無法繼續使用該對象
        //jedisCluster.close();
        for(String k: keySets2){
            System.out.println(k + " +++++++++++++++ " + jedisCluster.get(k));
        }
    }
}
package com.ssq.dmp.utils.jedis;

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

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Logger;

/**
 * JedisSentinelPool連接池的方式調用redis數據庫 
 * 
 */
public class JedisPoolUtil {
    
    private final static Logger logger = Logger.getLogger(JedisPoolUtil.class.getName());
    
    private static JedisSentinelPool pool = null;
 
    public static Properties getJedisProperties() {
        Properties config = new Properties();
        InputStream is = null;
        try {
            is = JedisPoolUtil.class.getClassLoader().getResourceAsStream("config.properties");
            config.load(is);
        } catch (IOException e) {
            logger.info(e.getMessage());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    logger.info(e.getMessage());
                }
            }
        }
        return config;
    }
 
    /**
     * 創建連接池
     *
     */
    private static void createJedisPool() {
        // 建立連接池配置參數
        JedisPoolConfig config = new JedisPoolConfig();
        Properties prop = getJedisProperties();
        // 設置最大連接數
        config.setMaxTotal(Integer.valueOf(prop.getProperty("redis.MAX_ACTIVE")));
        // 設置最大阻塞時間,記住是毫秒數milliseconds
        config.setMaxWaitMillis(Integer.valueOf(prop.getProperty("redis.MAX_WAIT")));
        // 設置空間連接
        config.setMaxIdle(Integer.valueOf(prop.getProperty("redis.MAX_IDLE")));
        // jedis實例是否可用
        boolean borrow = prop.getProperty("redis.TEST_ON_BORROW") == "false" ? false : true;
        config.setTestOnBorrow(borrow);
        
        String masterName = "master001";
        Set<String> sentinels = new HashSet<String>();
        
        String serviceAddressPort1 = prop.getProperty("redis.ADRESS") + ":" + prop.getProperty("redis.PORT1");
        String serviceAddressPort2 = prop.getProperty("redis.ADRESS") + ":" + prop.getProperty("redis.PORT2");
        String serviceAddressPort3 = prop.getProperty("redis.ADRESS") + ":" + prop.getProperty("redis.PORT3");
        sentinels.add(serviceAddressPort1);
        sentinels.add(serviceAddressPort2);
        sentinels.add(serviceAddressPort3);
        pool = new JedisSentinelPool(masterName, sentinels, config);
    }
 
    /**
     * 在多線程環境同步初始化
     */
    private static synchronized void poolInit() {
        if (pool == null)
            createJedisPool();
    }
 
    /**
     * 獲取一個jedis 對象
     *
     * @return
     */
    public static Jedis getJedis() {
        if (pool == null)
            poolInit();
        return pool.getResource();
    }
 
    /**
     * 釋放一個連接
     *
     * @param jedis
     */
    @SuppressWarnings("deprecation")
    public static void returnRes(Jedis jedis) {
        pool.returnResource(jedis);
    }
 
    /**
     * 銷燬一個連接
     *
     * @param jedis
     */
    @SuppressWarnings("deprecation")
    public static void returnBrokenRes(Jedis jedis) {
        pool.returnBrokenResource(jedis);
    }
}

jedisConfig.properties

#jedisCluster連接配置

#redisCluster實例地址
servers = 192.168.206.178:7001,192.168.206.178:7002,192.168.206.178:7003,192.168.206.178:7004,192.168.206.178:7005,192.168.206.178:7006
#連接redisCluster實例超時時間
connectionTimeout = 300000
#讀寫redisCluster實例超時時間
soTimeout = 300000
#連接redisCluster實例重試次數
maxAttempts = 6

#jedis連接池配置
#連接池最大連接數
maxTotal = 200
#獲取連接池連接最大等待時間(毫秒)
maxWaitMillis = 15000
#最大空閒連接數
maxIdle = 50
#最小空閒連接數
minIdle = 10
#對拿到的connection進行validateObject校驗
testOnBorrow = false
#從連接池獲取不到連接則阻塞
blockWhenExhausted = true
#連接對象後進先出
lifo = true
#歸還連接到池時測試連接
testOnReturn = false
#測試連接池空閒的連接
testWhileIdle = true
#測試連接池空閒連接的時間間隔,testWhileIdle=true時生效
timeBetweenEvictionRunsMillis = 30000


#監控數據-鍵標識(分別是數據處理監控,鏈路監控,查詢監控,預訂監控)
cluster.key.monitor.dataProcess = CSANTI_MONITOR_DP
cluster.key.monitor.linkProcess = CSANTI_MONITOR_LP
cluster.key.monitor.query = CSANTI_MONITOR_QUERY
cluster.key.monitor.book = CSANTI_MONITOR_BOOK
#監控數據有效期-單位秒  86400s=24h
cluster.exptime.monitor = 86400

#反爬黑名單數據-鍵標識
cluster.key.anti_black_list = CSANTI_ANTI_BLACK

#反爬黑名單數據有效期-單位秒
cluster.exptime.anti_black_list = 3600

#反佔座黑名單數據-鍵標識
cluster.key.ocp_black_list = CSANTI_OCP_BLACK

#反佔座黑名單數據有效期-單位秒
cluster.exptime.ocp_black_list = 3600

#Mysql-黑名單是否改變標識:BlackChangeFlag(默認值false)
#Mysql-流程是否改變標識:ProcessChangeFlag(默認值false)
#Mysql-過濾規則是否改變標識:FilterChangeFlag(默認值false)
#Mysql-規則是否改變標識:AnalyzeRuleChangeFlag(默認值false)
#redis是否宕機標識(默認值no)

##以下配置爲redis單節點或主從集羣使用
#jedis連接池配置
#連接池最大連接數
#maxTotal = 200
#獲取連接池連接最大等待時間(毫秒)
#maxWaitMillis = 15000
#最大空閒連接數
#maxIdle = 50
#最小空閒連接數
#minIdle = 10
#對拿到的connection進行validateObject校驗
#testOnBorrow = false
#從連接池獲取不到連接則阻塞
#blockWhenExhausted = true
#連接對象後進先出
#lifo = true
#歸還連接到池時測試連接
#testOnReturn = false
#測試連接池空閒的連接
#testWhileIdle = true
#測試連接池空閒連接的時間間隔,testWhileIdle=true時生效
#timeBetweenEvictionRunsMillis = 30000
#哨兵模式中的主機名
#MASTER = master001
#主從機地址+端口號
#SENTINEL_1 = 192.168.30.161:26381
#SENTINEL_2 = 192.168.30.161:26382
#SENTINEL_3 = 192.168.30.161:26383

#庫序號-監控數據庫
#db.index.monitor = 0
#監控數據庫-監控數據有效期-單位秒
#db.exptime.monitor = 3600
#庫序號-反爬結果黑名單數據庫
#db.index.anti_black_list = 5
#反爬庫-黑名單有效期-單位秒
#db.exptime.anti_black_list = 3600
#庫序號-mysql配置項數據更新標識數據庫
#db.index.configuration_change = 2
#庫序號-保存流量總和,用於前端顯示(僅前端使用)
#db.index.flow_data_sum = 7

注意

在這裏插入圖片描述
原因:我們使用的是redis3.0的集羣,用jedis的JedisCluster.close()方法造成的集羣連接關閉的情況。 jedisCluster內部使用了池化技術,每次使用完畢都會自動釋放Jedis因此不需要關閉

單機模式

單機模式需要手動close

package com.ssq.dmp.utils

import redis.clients.jedis.{Jedis, JedisPool, JedisPoolConfig}


object JedisConnectionPool{
  val conf = new JedisPoolConfig()
  //最大連接數,
  conf.setMaxTotal(20)
  //最大空閒連接數
  conf.setMaxIdle(10)
  //當調用borrow Object方法時,是否進行有效性檢查 -->
  conf.setTestOnBorrow(true)
  //10000代表超時時間(10秒)
  val pool = new JedisPool(conf, "slave2", 6379, 10000)

  def getConnection(): Jedis = {
    pool.getResource
  }

  def main(args: Array[String]): Unit = {
    val jedis = getConnection()
    println(jedis.get("sss"))
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章