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