springboot 學習之路 21 (集成redis集群做緩存架構)


redis集群:

  采用三主三從架構,住喲啊為了防止redis單節點故障宕機。采用redis集群是整個緩存體系更加文檔高效運行。

  在介紹redis集群充當緩存架構之前,先介紹一下redis集群的搭建:有兩種方式:

    第一種,基於ruby環境搭建 :redis介紹(6)集群(ruby)

    第二種:基於redis原始命令搭建 :redis介紹 (8) window 下redis的集群(cluster命令)

  兩種任何一種都可以。假設已經搭建好redis集群並已經啟動,測試通過,現在來配置redis集群充當springboot項目的緩存。

緩存架構配置:

  第一步:引入pom

    

  第二步:修改application文件

    

   第三步:redisconfig

    

    源碼如下:

    

 1 package com.xf.station.common.rediscluster;
 2 
 3 import com.alibaba.fastjson.serializer.SerializerFeature;
 4 import com.alibaba.fastjson.support.config.FastJsonConfig;
 5 import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.beans.factory.annotation.Value;
 8 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 9 import org.springframework.cache.CacheManager;
10 import org.springframework.cache.annotation.CachingConfigurerSupport;
11 import org.springframework.cache.annotation.EnableCaching;
12 import org.springframework.context.annotation.Bean;
13 import org.springframework.context.annotation.Configuration;
14 import org.springframework.data.redis.cache.RedisCacheConfiguration;
15 import org.springframework.data.redis.cache.RedisCacheManager;
16 import org.springframework.data.redis.cache.RedisCacheWriter;
17 import org.springframework.data.redis.connection.RedisConnectionFactory;
18 import org.springframework.data.redis.serializer.RedisSerializationContext;
19 import org.springframework.data.redis.serializer.StringRedisSerializer;
20 import redis.clients.jedis.HostAndPort;
21 import redis.clients.jedis.JedisCluster;
22 import redis.clients.jedis.JedisPoolConfig;
23 
24 import java.time.Duration;
25 import java.util.HashSet;
26 import java.util.Set;
27 
28 /**
29  * @author huhy
30  * @ClassName:RedisConfig
31  * @date 2018/9/26 13:29
32  * @Description: redis集群
33  */
34 @Configuration
35 @ConditionalOnClass({JedisCluster.class})
36 @EnableCaching
37 public class RedisConfig extends CachingConfigurerSupport {
38     @Value("${spring.redis.cluster.nodes}")
39     private String clusterNodes;
40     @Value("${spring.redis.timeout}")
41     private int timeout;
42     @Value("${spring.redis.lettuce.pool.max-idle}")
43     private int maxIdle;
44     @Value("${spring.redis.lettuce.pool.max-wait}")
45     private long maxWaitMillis;
46     @Value("${spring.redis.commandTimeout}")
47     private int commandTimeout;
48 
49     @Autowired
50     private RedisConnectionFactory redisConnectionFactory;
51 
52     @Bean
53     public JedisCluster getJedisCluster() {
54         String[] cNodes = clusterNodes.split(",");
55         Set<HostAndPort> nodes = new HashSet<>();
56         // 分割出集群節點
57         for (String node : cNodes) {
58             String[] hp = node.split(":");
59             nodes.add(new HostAndPort(hp[0],Integer.parseInt(hp[1])));
60         }
61         JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
62         jedisPoolConfig.setMaxIdle(maxIdle);
63         jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
64         // 創建集群對象
65       JedisCluster jedisCluster = new JedisCluster(nodes,commandTimeout);
66         return new JedisCluster(nodes,commandTimeout,jedisPoolConfig);
67     }
68 
69     @Bean
70     @Override
71     public CacheManager cacheManager() {
72         // 初始化一個RedisCacheWriter
73         RedisCacheWriter cacheManager = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
74         // 設置默認過期時間:2 分鍾
75         RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
76                 .entryTtl(Duration.ofMinutes(1))
77                 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
78                 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer()));
79 
80         RedisCacheManager redisCacheManager = new RedisCacheManager(cacheManager, defaultCacheConfig);
81 
82         return  redisCacheManager;
83     }
84     public FastJsonRedisSerializer<Object> fastJsonRedisSerializer() {
85         FastJsonConfig fastJsonConfig = new FastJsonConfig();
86         fastJsonConfig.setSerializerFeatures(
87                 SerializerFeature.WriteNullListAsEmpty,
88                 SerializerFeature.WriteDateUseDateFormat,
89                 SerializerFeature.WriteEnumUsingToString,
90                 SerializerFeature.WriteClassName);
91         FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
92         fastJsonRedisSerializer.setFastJsonConfig(fastJsonConfig);
93         return fastJsonRedisSerializer;
94     }
95 
96 }

 

  第四步:1啟動測試。注意我在redisconfiug中已經開始緩存了,就不用在啟動類上寫了。

    測試結果如下:

    

 

 


 

使用外置redis做緩存:

  springboot默認配置redis是通過application配置文件來做的,下面我采用自定義的配置來實現:

    1> 使用自定義的配置替換原有的RedisTemplate:

      

package com.newfiber.water.core.redis;

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.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
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.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.Duration;

/**
 * @author : HUHY
 * @Project_name:water-system_yiwu
 * @date:2019/8/10 15:53
 * @email:hhy_0602@163.com
 * @description:{todo}
 */
@Configuration
@EnableCaching //開啟緩存支持
public class RedisConfig extends CachingConfigurerSupport {


    @Autowired
    private RedisProperties redisProperties;

    /**
     * 本地數據源 redis template
     *
     * @return
     */
    @Bean
    public RedisTemplate redisTemplateLocal() {

        /* ========= 基本配置 ========= */
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName(redisProperties.getCache_server_ip());
        configuration.setPort(redisProperties.getCache_server_port());
        configuration.setDatabase(redisProperties.getCache_server_dbindex());
        if (!ObjectUtils.isEmpty(redisProperties.getCache_server_auth())) {
            RedisPassword redisPassword = RedisPassword.of(redisProperties.getCache_server_auth());
            configuration.setPassword(redisPassword);
        }

        /* ========= 連接池通用配置 ========= */
        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxTotal(redisProperties.getCache_pool_max_active());
        genericObjectPoolConfig.setMaxIdle(redisProperties.getCache_pool_max_idle());
        genericObjectPoolConfig.setMaxWaitMillis(redisProperties.getCache_pool_max_wait());


        /* ========= lettuce pool ========= */
        LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
        builder.poolConfig(genericObjectPoolConfig);
        builder.commandTimeout(Duration.ofSeconds(redisProperties.getCache_server_timeout()));
        LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration, builder.build());
        connectionFactory.afterPropertiesSet();

        /* ========= 創建 template ========= */
        return createRedisTemplate(connectionFactory);
    }
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        System.out.println("-------------");
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(redisProperties.getCache_server_dbindex());
        redisStandaloneConfiguration.setHostName(redisProperties.getCache_server_ip());
        redisStandaloneConfiguration.setPort(redisProperties.getCache_server_port());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getCache_server_auth()));

        LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration.builder();
        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration,
                lettuceClientConfigurationBuilder.build());
        return factory;
    }/**
     * json 實現 redisTemplate
     * <p>
     * 該方法不能加 @Bean 否則不管如何調用,connectionFactory都會是默認配置
     *
     * @param redisConnectionFactory
     * @return
     */
    public RedisTemplate createRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

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

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
---------------------------測試 如下:
@Autowired
private RedisTemplate redisTemplateLocal; -------這個屬性名為上面配置中的方法名稱 和@Autowired有關


@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
Set keys = redisTemplateLocal.keys("*");
System.out.println(keys);
}
 

  springboot 使用自定義的redis座緩存:

  1>redis.properties:

    

  2> 配置redis的緩存:

    

package com.newfiber.water.core.redis;

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.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
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.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.Duration;

/**
 * @author : HUHY
 * @Project_name:water-system_yiwu
 * @date:2019/8/10 15:53
 * @email:hhy_0602@163.com
 * @description:{todo}
 */
@Configuration
@EnableCaching //開啟緩存支持
public class RedisConfig extends CachingConfigurerSupport {


    @Autowired
    private RedisProperties redisProperties;

  
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        System.out.println("-------------");
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(redisProperties.getCache_server_dbindex());
        redisStandaloneConfiguration.setHostName(redisProperties.getCache_server_ip());
        redisStandaloneConfiguration.setPort(redisProperties.getCache_server_port());
        redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getCache_server_auth()));

        LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder = LettuceClientConfiguration.builder();
        LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration,
                lettuceClientConfigurationBuilder.build());
        return factory;
    }

    @Bean
    @Override
    public CacheManager cacheManager() {
        // 初始化一個RedisCacheWriter
        RedisCacheWriter cacheManager = RedisCacheWriter.nonLockingRedisCacheWriter(lettuceConnectionFactory());
        // 設置默認過期時間:2 分鍾
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(1))
                .disableCachingNullValues();
        RedisCacheManager redisCacheManager = new RedisCacheManager(cacheManager, defaultCacheConfig);
        return  redisCacheManager;
    }

    /**
     * json 實現 redisTemplate
     * <p>
     * 該方法不能加 @Bean 否則不管如何調用,connectionFactory都會是默認配置
     *
     * @param redisConnectionFactory
     * @return
     */
    public RedisTemplate createRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

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

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

 啟動測試即可,緩存的數據就就進入自定義的redis中

  

      


免責聲明!

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



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