开发测试两不误,spring-cloud redis配置,动态切换redis集群单机环境

在我们开发项目过程中,使用redis时,经常遇到需要在开发、测试版本中切换redis的集群或单机环境参数,如果把redis的环境参数写死在程序代码中或只有一项目配置参数,那么在发布测试版本时就要来回的修改redis的配置参数并重新打包,非常的麻烦。
利用nacos的配置中心,我们可以让软件包动态地中nacos配置中心中读取redis的集群或单机环境配置参数,不过需要我们进行一定程度的程序改造。
1、首先在pom.xml中导入redis包

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
    	</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
		<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.7</version>
        </dependency>

2、利用spring提供的@ConditionalOnProperty标签动态从nacos配置中心读取redis环境参数

package com.acorn.core.redis;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ReadMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;

import lombok.extern.log4j.Log4j2;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.util.Pool;

@Configuration
@EnableAutoConfiguration
@ConditionalOnProperty(value = "spring.redis.enabled",havingValue = "true",matchIfMissing=true)
@Log4j2
public class RedisConfig {

	@Autowired
	RedisProperties redisProperties;


	@Bean
	public JedisPoolConfig getRedisPoolConfig() {
		JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
		jedisPoolConfig.setMaxIdle(redisProperties.getJedis().getPool().getMaxIdle());
		jedisPoolConfig.setMaxIdle(redisProperties.getJedis().getPool().getMinIdle());
		jedisPoolConfig.setMaxWaitMillis(redisProperties.getJedis().getPool().getMaxWait().getSeconds());
		return jedisPoolConfig;
	}


	@Bean
	@ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
	public Pool<Jedis> getJedisPoolModeSentinel() {
		Set<String> newNodes = new HashSet<>();
		for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
			newNodes.add(redisProperties.getSentinel().getNodes().get(i));
		}
		log.info("###spring.redis.mode:sentinel,ip:{}",newNodes);
		// 创建连接池
		JedisSentinelPool pool = new JedisSentinelPool(redisProperties.getSentinel().getMaster(), newNodes, getRedisPoolConfig(), 
		        Long.valueOf(redisProperties.getTimeout().toMillis()).intValue(), redisProperties.getPassword(), redisProperties.getDatabase());
		return pool;
	}
	@Bean
    @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "standalone")
    public Pool<Jedis> getJedisPoolModeStandalone() {
        JedisPool pool = new JedisPool(getRedisPoolConfig(), redisProperties.getHost(), redisProperties.getPort(),
                Long.valueOf(redisProperties.getTimeout().toMillis()).intValue(), redisProperties.getPassword());
        log.info("###spring.redis.mode:standalone,ip:{}",redisProperties.getHost());
        return pool;
    }
	
	/**
	 * @Description: 哨后模式:JedisConnectionFactory
	 * @date 2022年10月27日 下午4:57:06 
	 * @param jedisPoolConfig
	 * @return
	 */
	@Bean
    @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
    public JedisConnectionFactory jedisConnectionFactoryModeSentinel(JedisPoolConfig jedisPoolConfig) {
        RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
        redisSentinelConfiguration.setMaster(redisProperties.getSentinel().getMaster());
        redisSentinelConfiguration.setDatabase(redisProperties.getDatabase());
        redisSentinelConfiguration.setSentinels(getSentinelNodes());
        String password = redisProperties.getPassword();
        redisSentinelConfiguration.setPassword(RedisPassword.of(password.toCharArray()));
        JedisConnectionFactory objJedisConnectionFactory = new JedisConnectionFactory(redisSentinelConfiguration, jedisPoolConfig);
        return objJedisConnectionFactory;
    }
	/**
     * @Description: 单机模式:JedisConnectionFactory
     * @param jedisPoolConfig
     * @return
     */
	@Bean("redisConnectionFactory")
    @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "standalone")
    public JedisConnectionFactory jedisConnectionFactoryModeStandalone(JedisPoolConfig jedisPoolConfig) {
	    RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
        standaloneConfiguration.setDatabase(redisProperties.getDatabase());
        standaloneConfiguration.setHostName(redisProperties.getHost());
        standaloneConfiguration.setPassword(redisProperties.getPassword());
        standaloneConfiguration.setPort(redisProperties.getPort());
        JedisConnectionFactory objJedisConnectionFactory = new JedisConnectionFactory(standaloneConfiguration);
        return objJedisConnectionFactory;
    }
	@Bean
	@ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
	public RedissonClient createSentinelRedissonClient() {
		Config config = new Config();

		List<String> newNodes = new ArrayList<>();
		for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
			newNodes.add("redis://" + redisProperties.getSentinel().getNodes().get(i));
		}
		config.useSentinelServers()
        .addSentinelAddress(newNodes.toArray(new String[0]))
        .setMasterName(this.redisProperties.getSentinel().getMaster())
        .setPassword(this.redisProperties.getPassword())
        .setReadMode(ReadMode.SLAVE)
        .setTimeout(60000)
        .setRetryAttempts(3)
        .setRetryInterval(60000)
        //**此项务必设置为redisson解决之前bug的timeout问题关键*****
        .setPingConnectionInterval(60000)
        .setDatabase(redisProperties.getDatabase());

		return Redisson.create(config);
	}
	
	@Bean
    @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "standalone")
    public RedissonClient createStandaloneRedissonClient() {
        Config config = new Config();
        config.useSingleServer()
        .setAddress("redis://" +this.redisProperties.getHost()+":"+this.redisProperties.getPort())
        .setPassword(this.redisProperties.getPassword())
        .setTimeout(60000)
        .setRetryAttempts(3)
        .setRetryInterval(60000)
        //**此项务必设置为redisson解决之前bug的timeout问题关键*****
        .setPingConnectionInterval(60000);

        return Redisson.create(config);
    }

	@Bean
    public Set<RedisNode> getSentinelNodes() {
        Set<RedisNode> nodos = new HashSet<>();
        for (int i = 0; i < redisProperties.getSentinel().getNodes().size(); i++) {
            String[] split = redisProperties.getSentinel().getNodes().get(i).split(":");
            nodos.add(new RedisNode(split[0], Integer.parseInt(split[1])));
        }
        return nodos;
    }
}

3、修改原redisService,添加@ConditionalOnProperty标签,
标签与RedisConfig 保持一致即可。

@Service
@ConditionalOnProperty(value = "spring.redis.enabled",havingValue = "true",matchIfMissing=true)
public class DefaultJedisService implements IJedisService{
     //.....省略redis操作代码
     }

4、在nacos中添加redis参数配置
在这里插入图片描述

redis参数内容:

spring: 
  redis: 
    enabled: true
    mode: standalone  ##启用集群时这个参数为sentinel
    password: aaaaa
    timeout: 10000
    jedis:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 1
    sentinel:
      nodes: ip:6379,ip:6379,ip:6379
      master: mymaster
    database: 6
    host: ip
    port: 6379

在本例中启用集群时只需将mode: standalone
改为mode: sentinel即可,无需更改其它参数
样例下载地址【redis-demo:spring-cloud-nacos动态配置
文章虽然短,但确实很实用,你不加个关注再走吗

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值