SpringBoot

您所在的位置:网站首页 redis的哨兵模式+spring整合 SpringBoot

SpringBoot

2024-03-03 03:51| 来源: 网络整理| 查看: 265

一、SpringBoot--整合Lettuce redis

首先解释一下Lettuce客户端:

  Lettuce 和 Jedis 的都是连接Redis Server的客户端程序。Jedis在实现上是直连redis server,多线程环境下非线程安全,除非使用连接池,为每个Jedis实例增加物理连接。Lettuce基于Netty的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问,同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

1、添加依赖

org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2

2、添加redis配置

spring: redis: host: **** password:**** port: 6379 # 连接超时时间(毫秒) timeout: 1000 # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0 database: 0 # 连接池配置 lettuce: pool: # 连接池最大连接数(使用负值表示没有限制) 默认 8 max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 max-wait: -1 # 连接池中的最大空闲连接 默认 8 max-idle: 8 # 连接池中的最小空闲连接 默认 0 min-idle: 0

3、实现逻辑

@Autowired private StringRedisTemplate stringRedisTemplate; @Override public String testRedis(){ ExecutorService executorService = Executors.newFixedThreadPool(1000); IntStream.range(0, 1000).forEach(i -> executorService.execute(() -> stringRedisTemplate.opsForValue().increment("lcl",1))); System.out.println("lcl1=============" + stringRedisTemplate.opsForValue().get("lcl")); stringRedisTemplate.opsForValue().set("lcl1","val1"); String val1 = stringRedisTemplate.opsForValue().get("lcl1"); System.out.println("lcl1=============" + val1); String key = "redis:test:demo1"; User user = new User(); user.setId(100L); user.setUsername("u2"); user.setPassword("p2"); stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(user)); String valUser = stringRedisTemplate.opsForValue().get(key); System.out.println("redis:test:demo1=============" + valUser); User getUser = JSON.parseObject(valUser, User.class); System.out.println("redis:test:demo1=============" + getUser.getUsername()+ "========" + getUser.getPassword()); return null; }

测试结果:

 

 

 

 

 

 由于redis有String、list、set、zset、hash、geo等类型,因此使用时不止使用opsForValue()方法,具体的对应方法如下:

    opsForValue: 对应 String(字符串)

    opsForZSet: 对应 ZSet(有序集合)

    opsForHash: 对应 Hash(哈希)

    opsForList: 对应 List(列表)

    opsForSet: 对应 Set(集合)

    opsForGeo: 对应 GEO(地理位置)

二、Luttuce连接哨兵

  Luttuce连接哨兵,主要是需要做哨兵的配置以及CacheManager、RedisTemplate、RedisConnectionFactory这三个Bean实例。

  1、哨兵配置:主要是配置哨兵集合和master节点名称

spring: redis: password: # 连接超时时间(毫秒) timeout: 1000 # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0 database: 0 # 连接池配置 lettuce: #lettuce连接池 pool: # 连接池最大连接数(使用负值表示没有限制) 默认 8 max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 max-wait: -1 # 连接池中的最大空闲连接 默认 8 max-idle: 8 # 连接池中的最小空闲连接 默认 0 min-idle: 0 #哨兵增加的配置 sentinel: nodes: 8.131.245.53:26379,8.131.245.53.234:26380,8.131.245.53:26381 master: mymaster ###################以下为springcache增加的配置########################### cache: redis: use-key-prefix: true key-prefix: dev cache-null-values: false time-to-live: 20s

  2、配置哨兵(Bean:RedisConnectionFactory)

  主要是使用上一步的配置信息,创建一个Luttuce的连接工厂,其中有连接池相关的配置,同时有哨兵相关的配置。

@Configuration @ConfigurationProperties(prefix = "spring.redis.sentinel") @Data public class RedisSentinelConfig { private Set nodes; private String master; @Value("${spring.redis.timeout}") private long timeout; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.lettuce.pool.max-idle}") private int maxIdle; @Value("${spring.redis.lettuce.pool.min-idle}") private int minIdle; @Value("${spring.redis.lettuce.pool.max-wait}") private long maxWait; @Value("${spring.redis.lettuce.pool.max-active}") private int maxActive; @Bean public RedisConnectionFactory lettuceConnectionFactory() { RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration(master, nodes); redisSentinelConfiguration.setPassword(RedisPassword.of(password.toCharArray())); GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxIdle(maxIdle); genericObjectPoolConfig.setMinIdle(minIdle); genericObjectPoolConfig.setMaxTotal(maxActive); genericObjectPoolConfig.setMaxWaitMillis(maxWait); LettucePoolingClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder() .poolConfig(genericObjectPoolConfig) .build(); return new LettuceConnectionFactory(redisSentinelConfiguration, lettuceClientConfiguration); } }

  3、数据源配置(Bean:CacheManager)

  主要是根据上一步配置来创建一个RedisCacheManager,其实主要就是使用redis来作为缓存。同时将查询缓存转换异常的问题做了解决,并改变了序列化方式。

/* * 修改 CacheManager 接口,将默认序列化改为JSON序列化,并使用redis作为缓存 * */ @Configuration @EnableCaching//开启缓存 @ConfigurationProperties(prefix = "spring.cache.redis") public class SpringCacheRedisConfig { private Duration timeToLive = Duration.ZERO; public void setTimeToLive(Duration timeToLive) { this.timeToLive = timeToLive; } @Bean public CacheManager cacheManager(LettuceConnectionFactory factory) { RedisSerializer redisSerializer = new StringRedisSerializer(); //创建Json序列化对象 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 将默认序列化改为Jackson2JsonRedisSerializer序列化 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(timeToLive) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); // 使用redis作为缓存,进入 CacheManager 接口按Control+H查看 CacheManager 的实现类,其中 RedisCacheManager 与redis有关 RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }

  4、Redis模板配置(Bean:RedisTemplate)

  这里仍然是使用第2步中的连接工厂对象,来创建一个RedisTemplate对象

@Configuration public class RedisTemplateConfig { @Bean public RedisTemplate redisTemplate(LettuceConnectionFactory factory) { //创建Json序列化对象 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 将默认序列化改为Jackson2JsonRedisSerializer序列化 RedisTemplate template = new RedisTemplate(); template.setKeySerializer(jackson2JsonRedisSerializer);// key序列化 template.setValueSerializer(jackson2JsonRedisSerializer);// value序列化 template.setHashKeySerializer(jackson2JsonRedisSerializer);// Hash key序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化 template.setConnectionFactory(factory); template.afterPropertiesSet(); return template; } }

  5、测试

  至此,使用Springboot+Luttuce+sentinel的缓存框架已经搭建完毕,使用时,仍然与单机版一致

@Autowired private StringRedisTemplate stringRedisTemplate; public void testRedis(){ stringRedisTemplate.opsForValue().set("lcl1","val1"); String val1 = stringRedisTemplate.opsForValue().get("lcl1"); System.out.println("lcl1=============" + val1); }

  但是有个问题需要注意:

  (1)由于使用哨兵模式不需要在配置文件中配置redis的host,只需要配置哨兵集合及监控master的名称,在使用redis时,redis会从哨兵中获取master名称对应的host,因此当matser切换时,我们仍然可以直接访问新的master,而不需要调整代码。

  (2)有时我们只是使用的单机服务器模拟的哨兵,因此哨兵中监控的master配置ip为127.0.0.1,如果这样,实际上在代码中,其也是直接访问的127.0.0.1,那么就会造成项目虽然可以启动成功,但是redis不能访问的情况。

三、Luttuce连接集群

  和使用哨兵一致,需要配置集群以及CacheManager、RedisTemplate、RedisConnectionFactory这三个Bean实例。

  其中CacheManager、RedisTemplate完全一致,所以这里主要写一下集群的配置参数和RedisConnectionFactory的创建

  

spring: redis: password: # 连接超时时间(毫秒) timeout: 1000 # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0 database: 0 # 连接池配置 lettuce: #lettuce连接池 pool: # 连接池最大连接数(使用负值表示没有限制) 默认 8 max,active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 ,1 max,wait: -1 # 连接池中的最大空闲连接 默认 8 max,idle: 8 # 连接池中的最小空闲连接 默认 0 min,idle: 0 cluster: nodes: 8.131.245.53:8001, 8.131.245.53:8002, 8.131.245.53:8003, 8.131.245.53:8004, 8.131.245.53:8005, 8.131.245.53:8006 # 获取失败 最大重定向次数 max,redirects: 3 @Bean public LettuceConnectionFactory myLettuceConnectionFactory() { Map source = new HashMap(); source.put("spring.redis.cluster.nodes", environment.getProperty("spring.redis.cluster.nodes")); source.put("spring.redis.cluster.timeout", environment.getProperty("spring.redis.cluster.timeout")); source.put("spring.redis.cluster.max-redirects", environment.getProperty("spring.redis.cluster.max-redirects")); RedisClusterConfiguration redisClusterConfiguration; redisClusterConfiguration = new RedisClusterConfiguration(new MapPropertySource("RedisClusterConfiguration", source)); return new LettuceConnectionFactory(redisClusterConfiguration); }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3