RedisTemplateConfig sentinel(哨兵模式)/ cluster(集群模式) 常用配置 以及如何 一键配置切换

简介: RedisTemplateConfig sentinel(哨兵模式)/ cluster(集群模式) 常用配置 以及如何 一键配置切换

紧接着上文 《redisTemplete config sentinel(哨兵)模式 常用配置》


开发中经常会遇到一个场景,同样一套代码,对不同客户时也许客户要求的redis集群不一样,向我们面对银行A客户时他们要求只能用他们现有的哨兵集群,但面对另一个银行客户B时又只能用cluster集群 ,所以基于最小改动原则,尽量让代码保持不变,通过配置文件修改一个属性达到目的。


本文主要来说一下如何在代码中同时存在sentinel 哨兵模式,以及cluster 模式配置,并且可以通过配置文件(例如nacos, apollo,application.yml application.properties 等)达到一键式切换

package cn.goswan.orient.gateway.config;
import io.lettuce.core.ReadFrom;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
/**
 * RedisTemplate  config配置
 *
 * @author alan.wang
 */
// @EnableCaching TODO
@Configuration
@AllArgsConstructor
@AutoConfigureBefore(RedisAutoConfiguration.class)
@Slf4j
public class RedisTemplateConfig {
  @Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setHashKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    return redisTemplate;
  }
  @Bean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
    stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
    stringRedisTemplate.setConnectionFactory(redisConnectionFactory);
    return stringRedisTemplate;
  }
  @Autowired
  RedisProperties redisProperties;
  @Bean
  public GenericObjectPoolConfig poolConfig() {
    GenericObjectPoolConfig config = new GenericObjectPoolConfig();
    config.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
    config.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
    config.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
    config.setMaxWaitMillis(redisProperties.getLettuce().getPool().getMaxWait().toMillis());
    return config;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
  public RedisSentinelConfiguration redisSentinelConfiguration() {
    RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
    redisConfig.setMaster(redisProperties.getSentinel().getMaster());
    if(redisProperties.getSentinel().getNodes()!=null) {
      List<RedisNode> sentinelNode=new ArrayList<RedisNode>();
      for(String sen : redisProperties.getSentinel().getNodes()) {
        String[] arr = sen.split(":");
        sentinelNode.add(new RedisNode(arr[0],Integer.parseInt(arr[1])));
      }
      redisConfig.setDatabase(redisProperties.getDatabase());
      redisConfig.setPassword(redisProperties.getPassword());
      redisConfig.setSentinelPassword(redisConfig.getPassword());
      redisConfig.setSentinels(sentinelNode);
    }
    return redisConfig;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "sentinel")
  public RedisConnectionFactory redisConnectionFactory(@Qualifier("poolConfig") GenericObjectPoolConfig config,
                             RedisSentinelConfiguration redisConfig) {//注意传入的对象名和类型RedisSentinelConfiguration
    LettuceClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder().poolConfig(config).build();
    return new LettuceConnectionFactory(redisConfig, clientConfiguration);
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "cluster")
  public RedisClusterConfiguration redisClusterConfiguration() {
    RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(redisProperties.getCluster().getNodes());
    redisClusterConfiguration.setPassword(redisProperties.getPassword());
    return redisClusterConfiguration;
  }
  @Bean
  @ConditionalOnProperty(value = "spring.redis.mode",havingValue = "cluster")
  public RedisConnectionFactory redisConnectionFactory(RedisClusterConfiguration redisClusterConfiguration) {
    ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
        .enablePeriodicRefresh()
        .enableAllAdaptiveRefreshTriggers()
        .refreshPeriod(Duration.ofSeconds(5))
        .build();
    ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
        .topologyRefreshOptions(clusterTopologyRefreshOptions).build();
    LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder()
        .readFrom(ReadFrom.REPLICA_PREFERRED)
        .clientOptions(clusterClientOptions).build();
    return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
  }
}

可以看到最重点的配置其实就是


@ConditionalOnProperty 里面的配置可以随便自定义,只要达到能区分就好,这样重启之后就会按照配置生成指定bean并注入,下面是我的配置,我们用的是spring cloud nacos 配置中心

1.png

用其他的配置中心或者配置文件也是一样的

相关文章
|
监控 API 开发者
Sentinel之道:流控模式解析与深度探讨
Sentinel之道:流控模式解析与深度探讨
407 0
|
运维 监控 NoSQL
Redis Sentinel哨兵模式部署
Redis Sentinel哨兵模式部署
424 2
|
Prometheus Cloud Native 调度
Sentinel 新版本发布,提升配置灵活性以及可观测配套
Sentinel 新版本发布,提升配置灵活性以及可观测配套
1657 98
|
监控 算法 Java
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
321 0
|
Java Nacos Maven
Sentinel1.8.6更改配置同步到nacos(项目是Gateway)
Sentinel1.8.6 nacos springcloud springcloud-alibaba gateway
670 0
|
监控 NoSQL 程序员
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
345 5
|
NoSQL Linux Redis
Redis 6.X Sentinel 哨兵集群搭建
Redis 6.X Sentinel 哨兵集群搭建
369 5
|
Java UED Sentinel
微服务守护神:Spring Cloud Sentinel,让你的系统在流量洪峰中稳如磐石!
【8月更文挑战第29天】Spring Cloud Sentinel结合了阿里巴巴Sentinel的流控、降级、熔断和热点规则等特性,为微服务架构下的应用提供了一套完整的流量控制解决方案。它能够有效应对突发流量,保护服务稳定性,避免雪崩效应,确保系统在高并发下健康运行。通过简单的配置和注解即可实现高效流量控制,适用于高并发场景、依赖服务不稳定及资源保护等多种情况,显著提升系统健壮性和用户体验。
332 1
|
监控 Java Sentinel
使用Sentinel进行服务调用的熔断和限流管理(SpringCloud2023实战)
Sentinel是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
783 3
|
负载均衡 算法 Java
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
40岁老架构师尼恩分享了关于SpringCloud核心组件的底层原理,特别是针对蚂蚁集团面试中常见的面试题进行了详细解析。内容涵盖了Nacos注册中心的AP/CP模式、Distro和Raft分布式协议、Sentinel的高可用组件、负载均衡组件的实现原理等。尼恩强调了系统化学习的重要性,推荐了《尼恩Java面试宝典PDF》等资料,帮助读者更好地准备面试,提高技术实力,最终实现“offer自由”。更多技术资料和指导,可关注公众号【技术自由圈】获取。
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?