好记性不如烂笔头
首先你的redis集群必须能正常启动
1.引用包
<!-- redis依賴 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
<!-- redis分佈式锁架构(本文与此扎包无关除非你用到分布式锁) -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
2.在项目中编写JedisClusterFactory
package com.eprintServer.util.redis;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
//import org.springframework.core.io.Resource;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
/**
* Jedis集群工厂
* @author mj
* @Date 2020-04-14
*/
public class JedisClusterFactory implements InitializingBean,FactoryBean<JedisCluster>{
//对应spring redis配置文件中的 property的name
// private Resource addressConfig;
private JedisCluster jedisCluster;
/**
* 读取数据超時時間
*/
private int soTimeout;
/**
* 代表集群有几台redis
*/
private int maxRedirections;
/**
* 最大空闲数
*/
private int maxIdle;
/**
*最小空闲数
*/
private int minIdle;
/**
* 連接池最大連接數
*/
private int maxTotal;
/**
* 最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
*/
private long maxWaitMillis;
/**
* 连接最小空闲时间默認1000L * 60L * 30L --30分鐘
*/
private long minEvictableIdleTimeMillis;
/**
* 空闲連接檢測週期但聞毫秒 -1不檢測
*/
private long timeBetweenEvictionRunsMillis;
/**
* 连接超时时间
*/
private int connectionTimeout;
/**
* 密码
*/
private String password;
/**
* 实现 InitializingBean 的接口,初始化的 得到 jedisCluster
*/
public void afterPropertiesSet() throws Exception {
Set<HostAndPort> jedisClusterNode= this.parseHostAndPort();
//配置連接池作用
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
// #最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。 默認8
if(maxIdle > 0)genericObjectPoolConfig.setMaxIdle(maxIdle);
// #最小空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。 默認0
if(minIdle > 0)genericObjectPoolConfig.setMinIdle(minIdle);
// #(連接池最大連接數)在指定时刻通过pool能够获取到的最大的连接的jedis个数,默认值8
if(maxTotal > 0)genericObjectPoolConfig.setMaxTotal(maxTotal);
// #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
if(maxWaitMillis > 0 || maxWaitMillis == -1)genericObjectPoolConfig.setMaxWaitMillis(maxWaitMillis);
// #连接最小空闲时间默認1000L * 60L * 30L --30分鐘
if(minEvictableIdleTimeMillis > 0)genericObjectPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// #在空闲时检查有效性, 默认false
// genericObjectPoolConfig.setTestWhileIdle(true);
// #空闲連接檢測週期但聞毫秒 默認-1不檢測
// genericObjectPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
//是否打開jmx監控。這樣就可以jvm調優時。通過jconsole 或者 jvisualvm 看到詳細使用情況:默認是true
// genericObjectPoolConfig.setJmxEnabled(false);
// #在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;默認fasle
// genericObjectPoolConfig.setTestOnBorrow(false);
if(!isNull(password)) {
jedisCluster = new JedisCluster(jedisClusterNode, connectionTimeout, soTimeout, maxRedirections, password, genericObjectPoolConfig);
}else {
jedisCluster = new JedisCluster(jedisClusterNode, soTimeout, maxRedirections, genericObjectPoolConfig);
}
}
/**
* 实现 FactoryBean 的接口
* 获取 jedisCluster对象
*/
public JedisCluster getObject() throws Exception {
return jedisCluster;
}
/**
* 实现 FactoryBean 的接口
* 获取 jedisCluster的类型
*/
public Class<? extends JedisCluster> getObjectType() {
return (jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class);
}
/**
* 实现 FactoryBean 的接口
*/
public boolean isSingleton() {
return true;
}
/**
* 解析Jedis配置文件,看是否满足 IP和端口
* @return
*/
private Set<HostAndPort> parseHostAndPort() throws Exception{
// 正则表达式 匹配 ip和port
Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");
Set<HostAndPort> hostAndPorts = new HashSet<HostAndPort>();
//到時間采用配置中心獲取配置參數
InputStream ins = JedisClusterFactory.class.getResourceAsStream("/redis.properties");
if(ins!=null) {
try {
Properties properties = new Properties();
// properties.load(this.addressConfig.getInputStream());
properties.load(ins);
for(Object key : properties.keySet()){
// 如果key不是以 address的值 开头,则continue
if(!((String)key).startsWith("address")){
continue;
}
// 根据 key从properties中取出值
String valus = (String) properties.get(key);
// 判断取出的value是否是ip和port
boolean isIPProt = p.matcher(valus).matches();
if(!isIPProt){
throw new IllegalArgumentException("ip和port不合法!");
}
String[] ipAndPort = valus.split(":");
HostAndPort hostAndPort = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
hostAndPorts.add(hostAndPort);
}
if(!isNull(properties.getProperty("redis.soTimeout")))soTimeout = Integer.valueOf(properties.getProperty("redis.soTimeout").trim());
if(!isNull(properties.getProperty("redis.maxRedirections")))maxRedirections = Integer.valueOf(properties.getProperty("redis.maxRedirections").trim());
if(!isNull(properties.getProperty("redis.maxIdle")))maxIdle = Integer.valueOf(properties.getProperty("redis.maxIdle").trim());
if(!isNull(properties.getProperty("redis.minIdle")))minIdle = Integer.valueOf(properties.getProperty("redis.minIdle").trim());
if(!isNull(properties.getProperty("redis.maxTotal")))maxTotal = Integer.valueOf(properties.getProperty("redis.maxTotal").trim());
if(!isNull(properties.getProperty("redis.maxWaitMillis")))maxWaitMillis = Long.valueOf(properties.getProperty("redis.maxWaitMillis").trim());
if(!isNull(properties.getProperty("redis.minEvictableIdleTimeMillis")))minEvictableIdleTimeMillis = Long.valueOf(properties.getProperty("redis.minEvictableIdleTimeMillis").trim());
if(!isNull(properties.getProperty("redis.connectionTimeout")))connectionTimeout = Integer.valueOf(properties.getProperty("redis.connectionTimeout").trim());
if(!isNull(properties.getProperty("redis.password")))password = properties.getProperty("redis.password").trim();
} catch (Exception e) {
e.printStackTrace();
throw new Exception("解析 jedis 配置文件失败!");
}
}else {
try{
//此 方法使用的是 apollo 配置中心調用參數
Config config = ConfigService.getConfig("public_dubbo");
if(!isNull(config.getProperty("redis.soTimeout",null)))soTimeout = Integer.valueOf(config.getProperty("redis.soTimeout",null).trim());
if(!isNull(config.getProperty("redis.maxRedirections",null)))maxRedirections = Integer.valueOf(config.getProperty("redis.maxRedirections",null).trim());
if(!isNull(config.getProperty("redis.maxIdle",null)))maxIdle = Integer.valueOf(config.getProperty("redis.maxIdle",null).trim());
if(!isNull(config.getProperty("redis.minIdle",null)))minIdle = Integer.valueOf(config.getProperty("redis.minIdle",null).trim());
if(!isNull(config.getProperty("redis.maxTotal",null)))maxTotal = Integer.valueOf(config.getProperty("redis.maxTotal",null).trim());
if(!isNull(config.getProperty("redis.maxWaitMillis",null)))maxWaitMillis = Long.valueOf(config.getProperty("redis.maxWaitMillis",null).trim());
if(!isNull(config.getProperty("redis.minEvictableIdleTimeMillis",null)))minEvictableIdleTimeMillis = Long.valueOf(config.getProperty("redis.minEvictableIdleTimeMillis",null).trim());
if(!isNull(config.getProperty("redis.connectionTimeout",null)))connectionTimeout = Integer.valueOf(config.getProperty("redis.connectionTimeout",null).trim());
if(!isNull(config.getProperty("redis.password",null)))password = config.getProperty("redis.password",null);
String address = config.getProperty("redis.address",null);
if(!isNull(address)) {
String[] ip = address.split(",");
for (String str : ip) {
boolean isIPProt = p.matcher(str).matches();
if(!isIPProt){
throw new IllegalArgumentException("ip和port不合法!");
}
String[] ipAndPort = str.split(":");
HostAndPort hostAndPort = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1]));
hostAndPorts.add(hostAndPort);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
}
return hostAndPorts;
}
public static boolean isNull(String arg) {
if (arg == null)
return true;
if ("".equals(arg))
return true;
if ("".equals(arg.trim()))
return true;
return false;
}
// set方法
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
// public void setAddressConfig(Resource addressConfig) {
// this.addressConfig = addressConfig;
// }
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
public void setMaxRedirections(int maxRedirections) {
this.maxRedirections = maxRedirections;
}
public void setConnectionTimeout(int connectionTimeout) {
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
public void setPassword(String password) {
this.password = password;
}
public void setMaxWaitMillis(long maxWaitMillis) {
this.maxWaitMillis = maxWaitMillis;
}
}
3.在你的ApplicationContext-main.xml 中 添加指定你新建的类地址
<!-- 配置reids 集裙工厂 -->
<bean id="jedisCluster" class="com.eprintServer.util.redis.JedisClusterFactory">
</bean>
4.在你的action 类或者 Controller 类注入进来就可以了
@Resource
private JedisCluster jedisCluster;
这是我的redis 配置
#注意,如果没有password,此处不设置值
redis.password=
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
redis.maxIdle=300
#最小空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
redis.minIdle=8
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;默認fasle
redis.testOnBorrow=true
#在指定时刻通过pool能够获取到的最大的连接的jedis个数,默认值8
redis.maxTotal=100
#在空闲时检查有效性, 默认false
redis.testWhileIdle=false
#连接最小空闲时间(毫秒)默認 1000L * 60L * 30L
redis.minEvictableIdleTimeMillis=900000
#读取数据超時時間(毫秒)
redis.soTimeout=300000
# 连接超时时间
redis.connectionTimeout=300000
#總共有多少台redis集裙
redis.maxRedirections=6
#// Adding replica 192.168.41.30:6380 to 192.168.41.65:6379
#// Adding replica 192.168.41.40:6380 to 192.168.41.42:6379
#// Adding replica 192.168.41.20:6380 to 192.168.41.70:6379
#集裙地址以及端口
address1=192.168.41.40:6379
address2=192.168.41.65:6379
address3=192.168.41.70:6379
address4=192.168.41.20:6380
address5=192.168.41.30:6380
address6=192.168.41.40:6380