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中
本文来自博客园,作者:huhy,转载请注明原文链接:https://www.cnblogs.com/huhongy/p/9706879.html

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号