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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM