每日学习Java之一万个为什么

Nacos 负载均衡

基于Ribbon

  • 轮询
  • 随机
  • 可用过滤:先过滤由于多次访问故障处于熔断的服务,以及并发连接数超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问。
  • 加权响应时间:根据每个服务实例的平均响应时间计算权重,响应时间越快权重越高,被选中的几率越大。刚开始使用RoundRobin轮询策略,等待足够数据后切换到基于权重的选择
  • 重试
  • 最佳可用:选择除故障实例外的请求数量最少的实例
  • 区域规避:复合判断server所属区域的性能和server的可用性选择服务器

基于Spring Cloud LoadBalancer

随着Spring Cloud 发展,官方推荐使用Spring Cloud LoadBalancer 替代 Ribbon。

  • 轮询
  • 随机
  • 加权(基于服务实例的权重选择)
  • LRT(最小响应时间)

自定义负载均衡策略

无论使用哪种接口提供的负载均衡方法,你都可以实现自己的负载均衡逻辑。通常需要创建一个新的类继承自相应地抽象类,覆盖其方法定义具体的负载均衡行为。之后在应用中注册该自定义的策略即可。

your-service-name:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Nacos yml 重要配置

配置项描述默认值
spring.application.name应用名称,用于服务注册与发现无(必须指定)
spring.cloud.nacos.discovery.server-addrNacos服务器地址,格式为IP:PORT无(必须指定)
spring.cloud.nacos.discovery.namespace命名空间ID,用于隔离不同的环境public
spring.cloud.nacos.discovery.group分组名称,同一命名空间下区分不同的服务分组DEFAULT_GROUP
spring.cloud.nacos.discovery.cluster-name集群名称,标识服务实例所属集群DEFAULT
spring.cloud.nacos.discovery.ip当前服务实例的IP地址自动获取
spring.cloud.nacos.discovery.port当前服务实例的端口自动获取
spring.cloud.nacos.discovery.ephemeral是否是临时实例(影响心跳机制),true为临时实例,false为持久化实例true
spring.cloud.nacos.config.server-addrNacos Config服务器地址,用于动态配置管理discovery.server-addr
spring.cloud.nacos.config.file-extension配置文件格式,支持properties, yaml等properties
spring.cloud.nacos.config.shared-configs[0].dataId共享配置的数据ID,可以有多个
spring.cloud.nacos.config.refresh-enabled是否开启自动刷新配置true
spring.cloud.nacos.config.timeout获取配置时超时时间(毫秒)3000

Nacos 多节点数据不一致时的数据恢复机制

当多个Nacos节点出现数据不一致的情况时,Nacos通过其内部机制来尝试恢复并保持数据的一致性。下面分别介绍服务发现模块和配置管理模块是如何处理这种情况的。

服务发现模块(Distro协议)

Distro协议概述

对于服务发现模块,Nacos采用了一种名为Distro的最终一致性协议。该协议允许在集群中的每个节点上都维护一份全量的服务注册信息副本。

健康检查与数据同步

  1. 健康检查:如果检测到某个节点的数据与其他节点不一致,Nacos会执行健康检查流程。
  2. 数据同步:一旦确定某个节点是健康的,它将作为数据源,向不健康的节点推送最新的服务注册信息。

心跳机制

  • 每个节点都会定期发送心跳给其他节点,以此确认它们的存活状态和数据版本。
  • 如果某个节点未能按时收到另一个节点的心跳,则认为该节点可能存在问题,并启动相应的数据同步或恢复过程。

配置管理模块(Raft协议)

Raft算法概述

对于配置管理模块,Nacos采用了Raft共识算法来保证强一致性。Raft算法通过选举领导节点(Leader)来协调所有写操作。

日志复制

  • Leader会将所有的写操作记录为日志条目,并将这些日志条目复制给所有的Follower。
  • 一旦大多数节点确认收到了新的日志条目,Leader就会提交这条日志,然后通知客户端操作成功完成。

异常处理

  • 如果Leader发生故障或者网络问题导致部分节点无法与Leader通信,Raft算法会触发一个新的领导者选举过程。
  • 新Leader当选后,它将根据自身的日志情况与其他节点同步数据,确保整个集群的数据一致性。

数据恢复策略

自动同步

无论是使用Distro还是Raft协议,一旦检测到数据不一致,Nacos都会尝试从健康的节点获取最新数据,并自动同步到受影响的节点上。

手动干预

在某些极端情况下,可能需要管理员手动干预来进行数据修复。例如,如果存在严重的数据冲突且无法自动解决,可以考虑通过备份恢复或者直接修改数据库来纠正问题。

以下是对 Nacos 配置管理OpenFeign 相关内容的详细说明,以 Markdown 格式整理,涵盖配置方法、共享配置、热更新、动态路由,以及 Feign 的连接池、日志、超时和重试配置:


Nacos 配置管理

怎么配置

1. 基础配置

步骤
  1. 启动 Nacos 服务:确保 Nacos 服务器已运行。
  2. 添加依赖(Spring Boot 项目):
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    
  3. 配置 application.yml
    spring:
      application:
        name: your-service-name  # 服务名称,用于 Nacos 配置匹配
      cloud:
        nacos:
          config:
            server-addr: 127.0.0.1:8848  # Nacos 服务器地址
            group: DEFAULT_GROUP        # 配置分组
            extension: yaml             # 配置文件格式(支持 properties/yaml)
    

共享配置

2. 共享配置

实现方式
  • 定义共享配置文件:在 Nacos 控制台创建一个配置文件(如 common-config.yaml),内容如下:
    shared-config:
      key1: value1
      key2: value2
    
  • 在服务中引用共享配置
    • 通过 @NacosProperty 注入
      @NacosProperty(name = "shared-config.key1", autoRefreshed = true)
      private String sharedValue;
      
    • 通过 @Value 注入
      @Value("${shared-config.key1}")
      private String sharedValue;
      

配置热更新

3. 配置热更新

实现步骤
  1. 启用自动刷新
    spring.cloud.nacos.config.refresh-enabled: true
    
  2. 使用 @RefreshScope 注解
    @RefreshScope
    @Component
    public class ConfigBean {
        @Value("${shared-config.key1}")
        private String configValue;
    
        // 通过 REST API 触发刷新(如访问 `/actuator/refresh`)
    }
    
  3. 监听配置变化(可选):
    @NacosConfigurationListener(
        dataId = "common-config.yaml",
        group = "DEFAULT_GROUP"
    )
    public class ConfigListener implements ConfigurationListener {
        @Override
        public void receive(ConfigChangeEvent event) {
            // 处理配置变更
        }
    }
    

动态路由

4. 动态路由

实现方式(结合 Nacos 服务发现):
  • 通过服务权重动态调整路由
    # 在 Nacos 控制台修改服务实例的权重(如将某个实例的权重设为 0 以隔离)
    
  • 结合 Sentinel 或 Spring Cloud Gateway
    // 示例:通过 Sentinel 的动态规则实现流量控制
    @Bean
    public SentinelGatewayFilterFactory sentinelGatewayFilterFactory() {
        return new SentinelGatewayFilterFactory();
    }
    

OpenFeign

连接池

1. 连接池配置

HTTP 客户端配置(如使用 HttpClient):
# application.yml
feign:
  client:
    config:
      default:
        client:
          config:
            your-service:  # 目标服务名称
              connectTimeout: 5000   # 连接超时(毫秒)
              readTimeout: 10000     # 读取超时(毫秒)
              maxTotalConnection: 200 # 连接池最大连接数
              maxConnectionsPerRoute: 50 # 每个路由的最大连接数

日志配置

2. 日志配置

调整 Feign 日志级别
logging:
  level:
    com.example.yourpackage: DEBUG  # 包名路径
    feign: DEBUG                    # 全局 Feign 日志
针对单个接口的配置
@FeignClient(
    name = "your-service",
    configuration = FeignLoggerConfig.class
)
public interface YourServiceClient {
    // 接口定义
}

// 配置类
@Configuration
public class FeignLoggerConfig {
    @Bean
    public Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL; // 输出请求/响应的详细日志
    }
}

超时配置

3. 超时配置

全局超时配置
feign:
  client:
    config:
      default:
        connectTimeout: 5000  # 连接超时(毫秒)
        readTimeout: 10000    # 读取超时(毫秒)
针对单个接口的配置
@FeignClient(
    name = "your-service",
    configuration = FeignTimeoutConfig.class
)
public interface YourServiceClient {
    // 接口定义
}

// 配置类
@Configuration
public class FeignTimeoutConfig {
    @Bean
    public Request.Options feignOptions() {
        return new Request.Options(5000, 10000); // connectTimeout, readTimeout
    }
}

重试配置

4. 重试配置

使用 Hystrix 或 Resilience4j
# 使用 Hystrix(需引入依赖)
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000
        circuitbreaker:
          errorThresholdPercentage: 50
          requestVolumeThreshold: 20
          sleepWindowInMilliseconds: 5000
        retry:
          max: 3  # 最大重试次数
使用 Spring Retry
@FeignClient(name = "your-service")
public interface YourServiceClient {
    @Retryable(maxAttempts = 3, backoff = @Backoff(delay = 1000))
    @GetMapping("/api/data")
    ResponseEntity<String> getData();
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~Yogi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值