SpringBoot整合Jedis可切换使用单机、哨兵、集群模式
admin
2024-01-19 11:29:02

前言

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

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

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

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

1.Jedis依赖

redis.clientsjedis3.7.1

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 nodes;private Integer maxRedirects;public List getNodes() {return nodes;}public void setNodes(List nodes) {this.nodes = nodes;}public Integer getMaxRedirects() {return maxRedirects;}public void setMaxRedirects(Integer maxRedirects) {this.maxRedirects = maxRedirects;}}public static class Sentinel{private List nodes;private String master;private String password;public List getNodes() {return nodes;}public void setNodes(List 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 {@Autowiredprivate RedisProperties redisProperties;@Autowiredprivate JedisProperties jedisProperties;@ConditionalOnProperty(value = "redis.model",havingValue = "standalone",matchIfMissing = true)@Beanpublic 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)@Beanpublic 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 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)@Beanpublic 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 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;@Overridepublic byte[] get(byte[] key) {return jedisCluster.get(key);}@Overridepublic String get(String key) {return jedisCluster.get(key);}@Overridepublic byte[] set(byte[] key, byte[] value) {jedisCluster.set(key,value);if(this.expire!=0){jedisCluster.expire(key,expire);}return value;}@Overridepublic String set(String key, String value) {jedisCluster.set(key,value);if(this.expire!=0){jedisCluster.expire(key,expire);}return value;}@Overridepublic byte[] set(byte[] key, byte[] value, int expire) {jedisCluster.set(key,value);if(expire!=0){jedisCluster.expire(key,expire);}return value;}@Overridepublic String set(String key, String value, int expire) {jedisCluster.set(key,value);if(expire!=0){jedisCluster.expire(key,expire);}return value;}@Overridepublic void del(byte[] key) {jedisCluster.del(key);}@Overridepublic 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;@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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);}}}@Overridepublic 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;@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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);}}}@Overridepublic 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

相关内容

热门资讯

俄媒:俄罗斯来华游客数量稳步增... 参考消息网11月19日报道 据俄罗斯自由媒体网11月17日报道,自9月15日中国对俄罗斯游客试行免签...
“根本不愁卖,来晚了就没了”!... “在网上看到了,特地来尝鲜。”近日,“00后”陈女士打卡了一款名为“奶皮子糖葫芦”的零食。这款零食由...
重磅发布!2026全球高端餐厅... 来源:携程美食林 当用户真实评价 与顶尖美食家的专业洞察交汇 呈现给所有人的不仅是榜单的更迭 更是携...
治愈系美食爱情微短剧《宴遇簪花... 作为泉州成功入选“世界美食之都”后的首部治愈系美食爱情微短剧,《宴遇簪花缘》今日正式公布首轮剧照。首...
【京·花果蜜】怀柔栗子天团,申... 谁能拒绝这一美味?栗子酥、冰栗、栗子蛋糕…个个都是实力派!这口百年老树的甜,你最爱哪一款?