SpringBoot配置Redis多集群数据源

共 17173字,需浏览 35分钟

 ·

2021-04-19 11:53

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

  作者 |  孙昌恒

来源 |  urlify.cn/uQBV3m

76套java从入门到精通实战课程分享

前提条件

  1. 两个数据源, 且两个数据源都是以集群方式部署的

  2. Lettuce 接入

  3. 本次测试的数据源

    • 数据源1: 192.168.10.6380

    • 数据源2: 192.168.10.6381

pom依赖文件

<!--pom.xml-->

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!--测试依赖包-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>

    <!--redis连接池-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.16</version>
    </dependency>

</dependencies>

配置文件

// application.yml

spring:
  redis:
    password: your'spassword      # 密码(默认为空)
    timeout: 6000  # 连接超时时长(毫秒)
    cluster:
      nodes: 192.168.10.1:6380
      max-redirects: 3 # 获取失败 最大重定向次数
    lettuce:
      pool:
        max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms      # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 10      # 连接池中的最大空闲连接
        min-idle: 5       # 连接池中的最小空闲连接

  secondaryRedis:
    cluster:
      nodes: 192.168.10.1:6381
      password: your'
spassword

多集群配置文件

// RedisConfig.java

package top.sunchangheng.multiredis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.HashMap;
import java.util.Map;

/*** 功能描述: 多集群数据源配置
 */
@Configuration
public class RedisConfig {

    @Autowired
    private Environment environment;

    /**
     * 配置lettuce连接池
     */
    @Bean
    @Primary
    @ConfigurationProperties (prefix = "spring.redis.cluster.lettuce.pool")
    public GenericObjectPoolConfig redisPool() {
        return new GenericObjectPoolConfig();
    }

    /**
     * 配置第一个数据源的
     */
    @Bean ("redisClusterConfig")
    @Primary
    public RedisClusterConfiguration redisClusterConfig() {

        Map<String, Object> source = new HashMap<>(8);
        source.put("spring.redis.cluster.nodes", environment.getProperty("spring.redis.cluster.nodes"));
        RedisClusterConfiguration redisClusterConfiguration;
        redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration",
                source));
        redisClusterConfiguration.setPassword(environment.getProperty("spring.redis.password"));
        return redisClusterConfiguration;

    }

    /**
     * 配置第一个数据源的连接工厂
     * 这里注意:需要添加@Primary 指定bean的名称,目的是为了创建两个不同名称的LettuceConnectionFactory
     */
    @Bean ("lettuceConnectionFactory")
    @Primary
    public LettuceConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig redisPool, @Qualifier (
            "redisClusterConfig") RedisClusterConfiguration redisClusterConfig) {
        LettuceClientConfiguration clientConfiguration =
                LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
        return new LettuceConnectionFactory(redisClusterConfig, clientConfiguration);
    }

    /**
     * 配置第一个数据源的RedisTemplate
     * 注意:这里指定使用名称=factory 的 RedisConnectionFactory
     * 并且标识第一个数据源是默认数据源 @Primary
     */
    @Bean ("redisTemplate")
    @Primary
    public RedisTemplate redisTemplate(@Qualifier ("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        return getRedisTemplate(redisConnectionFactory);

    }

    /**
     * 配置第二个数据源
     */
    @Bean ("secondaryRedisClusterConfig")
    public RedisClusterConfiguration secondaryRedisConfig() {

        Map<String, Object> source = new HashMap<>(8);
        source.put("spring.redis.cluster.nodes", environment.getProperty("spring.secondaryRedis.cluster.nodes"));
        RedisClusterConfiguration redisClusterConfiguration;
        redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration",
                source));
        redisClusterConfiguration.setPassword(environment.getProperty("spring.redis.password"));

        return redisClusterConfiguration;
    }

    @Bean ("secondaryLettuceConnectionFactory")
    public LettuceConnectionFactory secondaryLettuceConnectionFactory(GenericObjectPoolConfig redisPool, @Qualifier (
            "secondaryRedisClusterConfig") RedisClusterConfiguration secondaryRedisClusterConfig) {
        LettuceClientConfiguration clientConfiguration =
                LettucePoolingClientConfiguration.builder().poolConfig(redisPool).build();
        return new LettuceConnectionFactory(secondaryRedisClusterConfig, clientConfiguration);
    }

    /**
     * 配置第一个数据源的RedisTemplate
     * 注意:这里指定使用名称=factory2 的 RedisConnectionFactory
     */
    @Bean ("secondaryRedisTemplate")
    public RedisTemplate secondaryRedisTemplate(@Qualifier ("secondaryLettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        return getRedisTemplate(redisConnectionFactory);
    }

    /*** 功能描述: 根据连接工厂获取一个RedisTemplate
     */
    private RedisTemplate getRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }

}

到这里, 已经配置好了多集群数据源了, 但是需要注意的是: 注入redisTempalte 时, 需要根据名称进行依赖注入, 如下图中的测试案例

测试

// RedisTest.java

package top.sunchangheng.multiredis;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith (SpringRunner.class)
public class RedisTest {
    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    @Qualifier ("secondaryRedisTemplate")
    RedisTemplate<String, Object> secondaryRedisTemplate;

    @Autowired
    private Environment environment;

    @Test
    public void testEnvironment() {
        System.out.println("开始测试");
        String property = environment.getProperty("spring.secondaryRedis.cluster.nodes");
        System.out.println("property = " + property);
        System.out.println("over");
    }

    // 同时设置两个数据源的数据
    @Test
    public void testTemplateSet() {
        System.out.println("同时设置数据");
        redisTemplate.opsForValue().set("redis-key2""redisTemplate");
        secondaryRedisTemplate.opsForValue().set("redis-key2""secondaryRedisTemplate");
        System.out.println("over");
    }

    // 同时获取两个数据源的数据
    @Test
    public void testTemplateGet() {
        System.out.println("同时获取数据");
        Object key1 = redisTemplate.opsForValue().get("redis-key2");
        Object key2 = secondaryRedisTemplate.opsForValue().get("redis-key2");
        System.out.println("key1 = " + key1);
        System.out.println("key2 = " + key2);
        System.out.println("over");
    }
}






粉丝福利:Java从入门到入土学习路线图

👇👇👇

👆长按上方微信二维码 2 秒


感谢点赞支持下哈 

浏览 50
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报