SpringBoot整合Jedis可切换使用单机、哨兵、集群模式

前言

关于Redis的哨兵环境以及集群环境的搭建过程,可移步这里:

RedisCluster环境搭建https://blog.csdn.net/u014398573/article/details/127671087

Redis哨兵环境搭建https://blog.csdn.net/u014398573/article/details/127671023

话不多说,直接上代码吧,关注微信公众号: 【走进Java】 一起学习与交流!

1.Jedis依赖

<dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            <version>3.7.1version>
dependency>

2.SpringBoot配置文件,关于Redis的内容

# redis
spring.redis.database=0
spring.redis.host=192.168.50.130
spring.redis.port=6379
spring.redis.password=enginex123
#连接超时时间(毫秒)
spring.redis.timeout=6000
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=3000
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=1000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=100
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=5
# 集群模式配置
    #最大重定向次数
spring.redis.cluster.max-redirects=5
    #集群节点列表
spring.redis.cluster.nodes=192.168.0.10:6380,192.168.0.10:6381,192.168.0.10:6382,192.168.0.11:6380,192.168.0.11:6381,192.168.0.11:6382

# 哨兵模式配置
    #哨兵服务的密码,可能与redis本身密码是不用的,具体在sentinel配置文件里配置
spring.redis.sentinel.password=enginex123
    #主节点名称
spring.redis.sentinel.master=masterRedis
    #Sentinel节点列表
spring.redis.sentinel.nodes=192.168.50.130:26379
#redis环境模式 standalone:单机  cluster:集群 sentinel:哨兵
redis.model = sentinel

3.读取Redis配置属性类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author lisw
 * 微信公众号 ,走进Java
 * @description redis配置
 * @createDate 2022-11-01 16:23:40
 **/
@Data
@Configuration
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
    private String host;

    private Integer port;

    private String password;

    private Integer database;

    private int timeout;

    private Cluster cluster;

    private Sentinel sentinel;

    public static class Cluster {
        private List<String> nodes;

        private Integer maxRedirects;

        public List<String> getNodes() {
            return nodes;
        }

        public void setNodes(List<String> nodes) {
            this.nodes = nodes;
        }

        public Integer getMaxRedirects() {
            return maxRedirects;
        }

        public void setMaxRedirects(Integer maxRedirects) {
            this.maxRedirects = maxRedirects;
        }
    }

    public static class Sentinel{
        private List<String> nodes;
        private String master;
        private String password;

        public List<String> getNodes() {
            return nodes;
        }

        public void setNodes(List<String> nodes) {
            this.nodes = nodes;
        }

        public String getMaster() {
            return master;
        }

        public void setMaster(String master) {
            this.master = master;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
    }
}

4.读取Jedis配置属性

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @author lisw
 * 微信公众号 ,走进Java
 * @description redis配置
 * @createDate 2022-11-01 16:26:16
 **/
@Data
@Configuration
@Component
@ConfigurationProperties(prefix = "spring.redis.jedis.pool")
public class JedisProperties {
    private Integer maxIdle;

    private Integer maxWait;

    private Integer minIdle;

    private Integer maxActive;
}

5.Jedis 三种模式的Bean注入

SpringBoot,Jedis Bean注入,通过配置文件里面的redis.model属性决定使用什么模式,注入什么Bean,利用@ConditionalOnProperty注解

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.*;

import java.util.HashSet;
import java.util.Set;

/**
 * @author lisw
 * 微信公众号 ,走进Java
 * @description Redis Bean
 * @createDate 2022-11-01 16:27:56
 **/
@Configuration
public class RedisConfig {
    @Autowired
    private RedisProperties redisProperties;

    @Autowired
    private JedisProperties jedisProperties;

    @ConditionalOnProperty(value = "redis.model",havingValue = "standalone",matchIfMissing = true)
    @Bean
    public JedisPool redisPoolFactory() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(jedisProperties.getMaxIdle());
        jedisPoolConfig.setMaxWaitMillis(jedisProperties.getMaxWait());
        if (StringUtils.isNotBlank(redisProperties.getPassword())) {
            return new JedisPool(jedisPoolConfig, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getTimeout(), redisProperties.getPassword(), redisProperties.getDatabase());
        } else {
            return new JedisPool(jedisPoolConfig, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getTimeout(), null, redisProperties.getDatabase());
        }
    }

    @ConditionalOnProperty(value = "redis.model",havingValue = "sentinel",matchIfMissing = false)
    @Bean
    public JedisSentinelPool jedisSentinelPool(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(jedisProperties.getMaxIdle());
        jedisPoolConfig.setMaxWaitMillis(jedisProperties.getMaxWait());
        // 截取集群节点
        String[] sentinels = redisProperties.getSentinel().getNodes().toArray(new String[0]);
        // 创建set集合
        Set<String> nodes = new HashSet<>();
        // 循环数组把集群节点添加到set集合中
        for (String node : sentinels) {
            //添加节点
            nodes.add(node);
        }
        if(StringUtils.isNotBlank(redisProperties.getSentinel().getPassword())){
                return new JedisSentinelPool(redisProperties.getSentinel().getMaster(),nodes,jedisPoolConfig, redisProperties.getTimeout(),redisProperties.getTimeout(),
                        redisProperties.getPassword(),redisProperties.getDatabase(),null,redisProperties.getTimeout(),redisProperties.getTimeout(),
                        redisProperties.getSentinel().getPassword(),null);
        }else{
            return new JedisSentinelPool(redisProperties.getSentinel().getMaster(),nodes,jedisPoolConfig,redisProperties.getTimeout(),redisProperties.getPassword() );
        }
    }

    @ConditionalOnProperty(value = "redis.model",havingValue = "cluster",matchIfMissing = false)
    @Bean
    public JedisCluster getJedisCluster() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(jedisProperties.getMaxIdle());
        poolConfig.setMaxWaitMillis(jedisProperties.getMaxWait());
        poolConfig.setMinIdle(jedisProperties.getMinIdle());
        poolConfig.setMaxTotal(jedisProperties.getMaxActive());
        // 截取集群节点
        String[] cluster = redisProperties.getCluster().getNodes().toArray(new String[0]);
        // 创建set集合
        Set<HostAndPort> nodes = new HashSet<>();
        // 循环数组把集群节点添加到set集合中
        for (String node : cluster) {
            String[] host = node.split(":");
            //添加集群节点
            nodes.add(new HostAndPort(host[0], Integer.parseInt(host[1])));
        }
        //需要密码连接的创建对象方式
        return new JedisCluster(nodes, redisProperties.getTimeout(), 2000, redisProperties.getCluster().getMaxRedirects(), redisProperties.getPassword(), poolConfig);
    }
}

6.定义对业务使用的RedisManager接口

业务上使用时通过RedisManager注入进行使用,三种模式只会注入一个进去。代码如下

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import com.fibo.ddp.common.utils.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;

import java.util.*;

public interface RedisManager {

    byte[] get(byte[] key);
    String get(String key);
    byte[] set(byte[] key, byte[] value);
    String set(String key, String value);
    byte[] set(byte[] key, byte[] value, int expire);
    String set(String key, String value, int expire);
    void del(byte[] key);
    void del(String key);

}

7.RedisManage的集群模式实现

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;

import java.util.*;

/**
 * @author lisw
 * @program ddp-project
 * @description Redis管理器 集群模式
 * @createDate 2022-11-01 17:19:29
 **/
@Component
@ConditionalOnProperty(value = "redis.model",havingValue = "cluster",matchIfMissing = false)
@Slf4j
public class RedisManagerJedisCluster implements RedisManager{

    private int expire = 0;

    @Autowired(required = false)
    private JedisCluster jedisCluster;

    @Override
    public byte[] get(byte[] key) {
       return jedisCluster.get(key);
    }

    @Override
    public String get(String key) {
       return jedisCluster.get(key);
    }

    @Override
    public byte[] set(byte[] key, byte[] value) {
       jedisCluster.set(key,value);
       if(this.expire!=0){
           jedisCluster.expire(key,expire);
       }
      return value;
    }

    @Override
    public String set(String key, String value) {
        jedisCluster.set(key,value);
        if(this.expire!=0){
            jedisCluster.expire(key,expire);
        }
        return value;
    }

    @Override
    public byte[] set(byte[] key, byte[] value, int expire) {
        jedisCluster.set(key,value);
        if(expire!=0){
            jedisCluster.expire(key,expire);
        }
        return value;
    }

    @Override
    public String set(String key, String value, int expire) {
        jedisCluster.set(key,value);
        if(expire!=0){
            jedisCluster.expire(key,expire);
        }
        return value;
    }

    @Override
    public void del(byte[] key) {
        jedisCluster.del(key);
    }

    @Override
    public void del(String key) {
        jedisCluster.del(key);
    }
}

8.RedisManager的哨兵模式实现

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;

import java.util.*;

/**
 * @author lisw
 * @program ddp-project
 * @description Redis管理,哨兵模式实现
 * @createDate 2022-11-02 18:01:03
 **/
@Component
@ConditionalOnProperty(value = "redis.model",havingValue = "sentinel",matchIfMissing = false)
@Slf4j
public class RedisManagerJedisSentinel implements RedisManager{
    private int expire = 0;

    @Autowired(required = false)
    private JedisSentinelPool jedisPool;

    @Override
    public byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis =null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            jedis.close();
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String get(String key) {
        String value = null;
        Jedis jedis = jedisPool.getResource();
        try {
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public byte[] set(byte[] key, byte[] value, int expire) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String set(String key, String value, int expire) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public void del(byte[] key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
    }
    @Override
    public void del(String key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

}

9.RedisManager的单机模式实现

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.ParserConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;

import java.util.*;

/**
 * @author lisw
 * @program ddp-project
 * @description Redis管理,单机模式实现
 * @createDate 2022-11-01 17:09:01
 **/
@Component
@ConditionalOnProperty(value = "redis.model",havingValue = "standalone",matchIfMissing = true)
@Slf4j
public class RedisManagerJedisStandalone implements RedisManager {

    private int expire = 0;

    @Autowired(required = false)
    private JedisPool jedisPool;
    
    @Override
    public byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis =null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            jedis.close();
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String get(String key) {
        String value = null;
        Jedis jedis = jedisPool.getResource();
        try {
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public byte[] set(byte[] key, byte[] value, int expire) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public String set(String key, String value, int expire) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
        return value;
    }
    @Override
    public void del(byte[] key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPool.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            if (jedis != null) {
                jedisPool.returnResource(jedis);
            }
        }
    }
    @Override
    public void del(String key) {
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

}


10.业务代码注入RedisManager

@Autowired
private RedisManager redisManager;

11 最后

只需修改redis.model配置值就可以切换redis三种模式,值分别是:standalone,cluster,sentinel

你可能感兴趣的:(Redis,java,SpringBoot,spring,boot,java,redis)