spring 快速搭建 redis集群

好记性不如烂笔头java

首先你的redis集群必须能正常启动正则表达式

1.引用包redis

<!-- 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.在项目中编写JedisClusterFactoryspring

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 类注入进来就能够了apache

@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