暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringBoot配置Redis多集群数据源

IT哈哈 2021-04-19
1778

前提条件

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







          孙昌恒
          cnblogs.com/sunch/p/14665804.html

          文章转载自IT哈哈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论