连接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"))
}
}