spring boot配置同时支持单机和集群redis

该博客讲述了如何在Spring Boot应用中根据配置文件实现从单机Redis到集群Redis的无缝切换。作者在升级Spring Boot版本后,对原有配置进行了修改,特别是在`pom.xml`中更新依赖,并在`redis.properties`文件中使用ip:port的格式来定义集群节点,利用Spring框架中的`RedisClusterConfiguration`类进行解析。在`CacheConfig`类中也相应地调整了配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正式环境都是用集群版redis,开发用的单机版,领导要求通过配置文件来确定是单机还是集群,由于单机版已经实现了,那么准备就在单机版基础上进行开发,然后发现spring boot1.2版本已经比较老,就升级版本,由于升级了spring boot版本,对应其他配置也进行了修改。最终修改的配置如下:

 

pom.xml

<properties>
	<java.version>1.8</java.version>
	<spring.version>4.3.9.RELEASE</spring.version>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.8.RELEASE</version>
</parent>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
       <!--原来是spring-boot-starter-redis-->
</dependency>
<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.9.0</version>
</dependency>

 redis.properties文件基本没有变:

# REDIS (RedisProperties) 
# Redis服务器地址(集群用逗号分隔)
#spring.redis.host=xxx.xxx.xxx.xxx:xxxxx
spring.redis.host=xxx.xxx.xxx.xxx:xxxxx,xxx.xxx.xxx.xxx:xxxxx
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接超时时间(毫秒)
spring.redis.timeout=2000
spring.redis.max-redirects=8

 注意:host变成ip:port,集群多个ip和端口用“,”分割,为什么这样写spring框架中RedisClusterConfiguration类中就是这样分割。看一下源代码:

//RedisClusterConfiguration类:
private static final String REDIS_CLUSTER_NODES_CONFIG_PROPERTY = "spring.redis.cluster.nodes";  //默认是配置这样的
……
public RedisClusterConfiguration(PropertySource<?> propertySource) {

	notNull(propertySource, "PropertySource must not be null!");

	this.clusterNodes = new LinkedHashSet<RedisNode>();
        //有spring.redis.cluster.nodes配置,分割这个属性,添加node
	if (propertySource.containsProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY)) {
		appendClusterNodes(commaDelimitedListToSet(propertySource.getProperty(REDIS_CLUSTER_NODES_CONFIG_PROPERTY)
				.toString()));
	 }
         ……
	}
//函数会调用,用","分割:
public static String[] commaDelimitedListToStringArray(String str) {
	return delimitedListToStringArray(str, ",");
}
//然后用":"分割组装成RedisNode
private void appendClusterNodes(Set<String> hostAndPorts) {

	for (String hostAndPort : hostAndPorts) {
		addClusterNode(readHostAndPortFromString(hostAndPort));
	}
}

private RedisNode readHostAndPortFromString(String hostAndPort) {
	String[] args = split(hostAndPort, ":");

	notNull(args, "HostAndPort need to be seperated by  ':'.");
	isTrue(args.length == 2, "Host and Port String needs to specified as host:port");
	return new RedisNode(args[0], Integer.valueOf(args[1]).intValue());
}

 在cacheconfig类中变成这样的:

@Bean
	public RedisClusterConfiguration getClusterConfiguration() {
		if (host.split(",").length > 1) {
                        //如果是host是集群模式的才进行以下操作
			Map<String, Object> source = new HashMap<String, Object>();

			source.put("spring.redis.cluster.nodes", host);

			source.put("spring.redis.cluster.timeout", timeout);

			source.put("spring.redis.cluster.max-redirects", redirects);
                        //在源码的注释中可以看到是这样配置,以为这样写就不用在Connection中不用在认证,后来确定太天真了
source.put("spring.redis.cluster.password", password);

			return new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
		} else {
			return null;
		}

	}

	@Bean
	public JedisConnectionFactory jedisConnectionFactory() {
		if (host.split(",").length == 1) {
			JedisConnectionFactory factory = new JedisConnectionFactory();
			factory.setHostName(host.split(":")[0]);
			factory.setPort(Integer.valueOf(host.split(":")[1]));
			factory.setPassword(password);
			factory.setTimeout(timeout);
			return factory;
		} else {
			JedisConnectionFactory jcf = new JedisConnectionFactory(getClusterConfiguration());
			jcf.setPassword(password); //集群的密码认证
			return jcf;
		}

	}
//这样改造之后,redisTemplate模板就不用改了,之前写的redisUtil类也不用变了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值