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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: SpringBoot整合Jedis可利用配置文件一键切换使用单机、哨兵、集群模式

直接上代码吧

<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.1</version>
</dependency>

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

读取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;
        }
    }
}

读取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;
}

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

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);
    }
}

业务上使用时通过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);

}

集群模式实现

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);
    }
}

哨兵模式实现

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();
            }
        }
    }

}

单机模式实现

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();
            }
        }
    }

}

业务代码使用时,注入RedisManager即可

@Autowired
private RedisManager redisManager;

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

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7月前
|
Web App开发 编解码 Java
B/S基层卫生健康云HIS医院管理系统源码 SaaS模式 、Springboot框架
基层卫生健康云HIS系统采用云端SaaS服务的方式提供,使用用户通过浏览器即能访问,无需关注系统的部署、维护、升级等问题,系统充分考虑了模板化、配置化、智能化、扩展化等设计方法,覆盖了基层医疗机构的主要工作流程,能够与监管系统有序对接,并能满足未来系统扩展的需要。
233 5
|
3月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
4月前
|
缓存 NoSQL Java
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
|
6月前
|
Java Docker 容器
使用 Spring Boot 构建 Docker 镜像并进行多模式部署
使用 Spring Boot 构建 Docker 镜像并进行多模式部署
283 2
|
7月前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
564 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
7月前
|
JavaScript Java 测试技术
微信小程序基于BS模式的学生实习与就业管理springboot+vue.js附带文章和源代码设计说明文档ppt
微信小程序基于BS模式的学生实习与就业管理springboot+vue.js附带文章和源代码设计说明文档ppt
68 1
|
6月前
|
Java
springboot集成ElasticSearch(支持集群)
springboot集成ElasticSearch(支持集群)
360 0
|
7月前
|
NoSQL Java Redis
springboot之RedisTemplate的访问单机,哨兵,集群模式
以上是配置RedisTemplate以连接到单机、哨兵和集群模式的示例。在实际应用中,还可以根据需求配置连接池、序列化方式、超时等其他参数。
427 0
|
7月前
|
NoSQL Java Redis
SpringBoot集成Redis并使用Redis发布订阅模式
SpringBoot集成Redis并使用Redis发布订阅模式
304 3
|
7月前
|
Kubernetes Cloud Native Devops
云原生技术落地实现之二KubeSphere DevOps 系统在 Kubernetes 集群上实现springboot项目的自动部署和管理 CI/CD (2/2)
云原生技术落地实现之二KubeSphere DevOps 系统在 Kubernetes 集群上实现springboot项目的自动部署和管理 CI/CD (2/2)
162 1