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中