springboot项目中连接2个redis实例

springboot项目中连接2个redis实例

  • 基于JDK1.8 
  • Maven
     
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0-m4</version>
</dependency>


配置文件application.properties
############### Redis配置 start###############
#业务数据redis配置
spring.redis.jedis.pool.max-active=50
spring.redis.jedis.pool.max-wait=15
spring.redis.jedis.pool.max-idle=50
spring.redis.jedis.pool.min-idle=0
spring.redis.timeout=15
spring.redis.database=1
#spring.redis.host=192.169.1.71
#spring.redis.port=6379
spring.redis.password=123456
#如果是集群,不需要配置host和port,请配置cluster
spring.redis.cluster.nodes=192.169.1.71:7001,192.169.1.71:7002,192.169.1.71:7003,192.169.1.71:7004,192.169.1.71:7005,192.169.1.71:7006
spring.redis.cluster.max-redirects=3
#缓存数据redis配置
spring.redis2.jedis.pool.max-active=50
spring.redis2.jedis.pool.max-wait=5
spring.redis2.jedis.pool.max-idle=50
spring.redis2.jedis.pool.min-idle=0
spring.redis2.timeout=5
spring.redis2.database=1
spring.redis2.host=192.169.1.71
spring.redis2.port=6379
spring.redis2.password=123456
#如果是集群,不需要配置host和port,请配置cluster
#spring.redis2.cluster.nodes
=192.169.1.71:7001,192.169.1.71:7002,192.169.1.71:7003,192.169.1.71:7004,192.169.1.71:7005,192.169.1.71:7006 #spring.redis2.cluster.max-redirects=3 ################ Redis配置 end###############

可以看到上面有两个redis。 一个是存业务数据的redis称之为redis1,一个是存缓存数据的redis称之为redis2

 要连接两个redis实例需要重写两个RedisConnectionFactory

redis1

RedisConfig.java (配置类,自定义工厂RedisConnectionFactory,创建RedisTemplate)
package com.montnets.email.middleware.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.montnets.email.specmailgate.util.StrUtil;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.RedisStandaloneConfiguration;
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 org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * redis 配置类
 * @author  Void
 * @date 2019/5/25 11:34
 * @description:RedisConnectionFactory、RedisTemplate会自动装配
 * @version v2.0.0
 * @see {@link org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration}
 */
@Configuration
@EnableCaching
@Component
public class RedisConfig {

    //最大活跃数
    @Value("${spring.redis.jedis.pool.max-active:8}")
    private int maxActive;

    //最大等待数
    @Value("${spring.redis.jedis.pool.max-wait:-1}")
    private int maxWait;

    //最大核心线程数
    @Value("${spring.redis.jedis.pool.max-idle:8}")
    private int maxIdle;

    //最小核心线程数
    @Value("${spring.redis.jedis.pool.min-idle:0}")
    private int minIdle;

    //redis连接的超时时长
    @Value("${spring.redis.timeout:5}")
    private int timeOut;

    //redis连接的库
    @Value("${spring.redis.database:0}")
    private int database;
    //节点配置
    @Value("${spring.redis.cluster.nodes:#{null}}")
    private String nodes;

    //最大连接转移数
    @Value("${spring.redis.cluster.max-redirects:3}")
    private int maxRedirects;

    //单节点情况下redis的ip
    @Value("${spring.redis.host:#{null}}")
    private String host;

    //单节点情况下redis的端口
    @Value("${spring.redis.port:#{null}}")
    private Integer port;

    //redis的连接密码
    @Value("${spring.redis.password:#{null}}")
    private String password;

    /**
     * 创建redisTemplate
     * 所有序列化k/v都会默认使用{@link org.springframework.data.redis.serializer.JdkSerializationRedisSerializer}
     * 默认的序列化类用使用byte数组进行存储, 在使用redis可视化客户端看到都是乱码不直观
     * 使用StringRedisSerializer序列化Key,  Jackson2JsonRedisSerializer序列化值, 可以观察到对象结构层次
     * 
     * 
     * @return
     */
    @Bean
    @Qualifier("redisTemplate")
    public RedisTemplate<String, Object> redisTemplate() {
        Jackson2JsonRedisSerializer<Object> valueSerializer = jackson2JsonRedisSerializer();
        StringRedisSerializer keySerializer = new StringRedisSerializer();
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory());
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setValueSerializer(valueSerializer);
        redisTemplate.setHashKeySerializer(keySerializer);
        redisTemplate.setHashValueSerializer(valueSerializer);
        return redisTemplate;
    }

    /**
     * 定义序列化类
     *
     * @return
     */
    public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }

    /**
     * 连接配置
     * @return
     */
    @Bean
    public RedisConnectionFactory connectionFactory() {
        Map<String, Object> source = new HashMap<String, Object>();
        RedisClusterConfiguration redisClusterConfiguration;
        RedisStandaloneConfiguration redisStandaloneConfiguration;
        //连接池配置
        GenericObjectPoolConfig genericObjectPoolConfig =
                new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);

        //redis客户端配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
                builder =  LettucePoolingClientConfiguration.builder().
                commandTimeout(Duration.ofSeconds(timeOut));
        builder.poolConfig(genericObjectPoolConfig);
        LettuceClientConfiguration lettuceClientConfiguration = builder.build();

        //集群模式
        if(nodes !=null){
            source.put("spring.redis.cluster.nodes", nodes);
            source.put("spring.redis.cluster.max-redirects", maxRedirects);
            redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
            if(!StrUtil.isEmpty(password)){
                redisClusterConfiguration.setPassword(password);
            }
            //根据配置和客户端配置创建连接
            LettuceConnectionFactory lettuceConnectionFactory = new
                    LettuceConnectionFactory(redisClusterConfiguration,lettuceClientConfiguration);
//            lettuceConnectionFactory .afterPropertiesSet();
            return lettuceConnectionFactory;
        }else{
            //单机模式
            redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port);
            redisStandaloneConfiguration.setDatabase(database);
            if(!StrUtil.isEmpty(password)){
                redisStandaloneConfiguration.setPassword(password);
            }
            //根据配置和客户端配置创建连接工厂
            LettuceConnectionFactory lettuceConnectionFactory = new
                    LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration);
//            lettuceConnectionFactory .afterPropertiesSet();
            return lettuceConnectionFactory;

        }
    }
}
RedisService.java (redis服务类,提供操作redis的方法,装配redis1的redistemplate)
package com.montnets.email.middleware.redis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;import org.springframework.stereotype.Component;/**
 * redis缓存调用的Java方法
 * @author chenlinyan
 * @date 2019/5/25 11:34
 * @description:RedisTemplate会自动装配
 * @version v2.0.0
 * @see {@link org.springframework.boot.autoconfigure.data.redis}
 */
@Slf4j
@Component
public class RedisService {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

/** * 写入redis缓存 * @param key 键 * @param value value * @return */ public boolean set(final String key, Object value) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue(); operations.set(key, value); result = true; } catch (Exception e) { log.error("set key value error", e); } return result; }

  /** * 删除指定key * @param key * @return */ public boolean delete(String key){ return redisTemplate.delete(key); } }

redis2

Redis2Config.java (配置类,自定义工厂RedisConnectionFactory,创建RedisTemplate)
package com.montnets.email.middleware.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.montnets.email.specmailgate.util.StrUtil;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.RedisStandaloneConfiguration;
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 org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author :Void
 * @date :2019-09-17 09:21
 * @description:另一个redis的配置
 * @version: v1.0.0.23
 */

@Component
@Configuration
@EnableCaching
public class Redis2Config {

    //最大活跃数
    @Value("${spring.redis2.jedis.pool.max-active:8}")
    private int maxActive;

    //最大等待数
    @Value("${spring.redis2.jedis.pool.max-wait:-1}")
    private int maxWait;

    //最大核心线程数
    @Value("${spring.redis2.jedis.pool.max-idle:8}")
    private int maxIdle;

    //最小核心线程数
    @Value("${spring.redis2.jedis.pool.min-idle:0}")
    private int minIdle;

    //redis连接的超时时长
    @Value("${spring.redis2.timeout:5}")
    private int timeOut;

    //redis连接的库
    @Value("${spring.redis2.database:0}")
    private int database;
    //节点配置
    @Value("${spring.redis2.cluster.nodes:#{null}}")
    private String nodes;

    //最大连接转移数
    @Value("${spring.redis2.cluster.max-redirects:3}")
    private int maxRedirects;

    //单节点情况下redis的ip
    @Value("${spring.redis2.host:#{null}}")
    private String host;

    //单节点情况下redis的端口
    @Value("${spring.redis2.port:#{null}}")
    private Integer port;

    //redis的连接密码
    @Value("${spring.redis2.password:#{null}}")
    private String password;

    /**
     * 创建redisTemplate连接模板
     *
     * @return
     */
    @Primary
    @Bean
    @Qualifier("redisTemplate2")
    public RedisTemplate<String, Object> redisTemplate2() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory2());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(this.jackson2JsonRedisSerializer2());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(this.jackson2JsonRedisSerializer2());
        return redisTemplate;
    }

    /**
     * k-v的序列化
     *
     * @return
     */
    @Bean
    public Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer2() {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        return jackson2JsonRedisSerializer;
    }

    /**
     * 连接配置
     *
     * @return
     */
    @Primary
    @Bean
    public RedisConnectionFactory connectionFactory2() {
        Map<String, Object> source = new HashMap<String, Object>();
        RedisClusterConfiguration redisClusterConfiguration;
        RedisStandaloneConfiguration redisStandaloneConfiguration;
        //连接池配置
        GenericObjectPoolConfig genericObjectPoolConfig =
                new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxTotal(maxActive);
        genericObjectPoolConfig.setMaxWaitMillis(maxWait);
        genericObjectPoolConfig.setMaxIdle(maxIdle);
        genericObjectPoolConfig.setMinIdle(minIdle);

        //redis客户端配置
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder
                builder =  LettucePoolingClientConfiguration.builder().
                commandTimeout(Duration.ofSeconds(timeOut));
        builder.poolConfig(genericObjectPoolConfig);
        LettuceClientConfiguration lettuceClientConfiguration = builder.build();

        //集群模式
        if(nodes !=null){
            source.put("spring.redis.cluster.nodes", nodes);
            source.put("spring.redis.cluster.max-redirects", maxRedirects);
            redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source));
            if(!StrUtil.isEmpty(password)){
                redisClusterConfiguration.setPassword(password);
            }
            //根据配置和客户端配置创建连接工厂
            LettuceConnectionFactory lettuceConnectionFactory = new
                    LettuceConnectionFactory(redisClusterConfiguration,lettuceClientConfiguration);
//            lettuceConnectionFactory .afterPropertiesSet();
            return lettuceConnectionFactory;
        }else{
            //单机模式
            redisStandaloneConfiguration = new RedisStandaloneConfiguration(host,port);
            redisStandaloneConfiguration.setDatabase(database);
            if(!StrUtil.isEmpty(password)){
                redisStandaloneConfiguration.setPassword(password);
            }
            //根据配置和客户端配置创建连接
            LettuceConnectionFactory lettuceConnectionFactory = new
                    LettuceConnectionFactory(redisStandaloneConfiguration,lettuceClientConfiguration);
//            lettuceConnectionFactory .afterPropertiesSet();
            return lettuceConnectionFactory;

        }
    }

}
Redis2Service.java (redis服务类,提供操作redis的方法,装配redis1的redistemplate)
package com.montnets.email.middleware.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

/**
 * redis缓存调用的Java方法
 * @author chenlinyan
 * @date 2019/5/25 11:34
 * @description:RedisTemplate会自动装配
 * @version v2.0.0
 * @see {@link org.springframework.boot.autoconfigure.data.redis}
 */
@Slf4j
@Component
public class Redis2Service {

    @Autowired
    @Qualifier("redisTemplate2")
    private RedisTemplate redisTemplate;


    /**
     * 写入redis缓存
     * @param key 键
     * @param value value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            log.error("set key value error", e);
        }
        return result;
    }
    /**
     * 删除指定key
     * @param key
     * @return
     */
    public boolean delete(String key){
        return redisTemplate.delete(key);
    }

}

测试类

package com.montnets.test;

import com.montnets.email.MailgateApplication;
import com.montnets.email.middleware.redis.Redis2Service;
import com.montnets.email.middleware.redis.RedisService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * @author chenlinyan
 * @date 2019/6/17 10:35
 * @version v2.0.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MailgateApplication.class)
public class AppTest {


    @Resource
    private RedisService redisService;

    @Resource
    private Redis2Service redis2Service;

    @Test
    public void testSave() {
         //存数据到redis1中
         redisService.set("redis1","1111");
        //存数据到redis2中
        redis2Service.set("redis2","2222");
    }

}

参考地址  

LettuceConnectionFactory多配置,及配置原理详解 https://blog.csdn.net/qq_42394457/article/details/94493027

Spring boot配置多个Redis数据源操作实例 https://www.jianshu.com/p/c79b65b253fa

原文地址:https://www.cnblogs.com/kiko2014551511/p/11544729.html