在这里插入图片描述
Nacos 客户端 SDK (nacos-client.jar) 的核心职责是服务发现(从 Nacos Server 获取服务实例列表)和服务注册,它本身没有配置负载均衡算法(像 Ribbon 或 Spring Cloud LoadBalancer 那样)。

然而,Nacos 提供了实现负载均衡的基础数据和机制:

  1. 提供实例列表: Nacos Client 可以获取到目标服务的所有健康实例的列表(IP、端口)。
  2. 支持实例权重: Nacos 允许为每个服务实例设置一个权重 (weight) 值(默认为 1.0)。这个权重是实现加权类负载均衡策略的关键输入。

实际的负载均衡是由与 Nacos 集成的客户端负载均衡器实现的。在不同的技术栈中,这个负载均衡器可能不太一样:

  • Spring Cloud: 早期使用 Netflix Ribbon (现已维护模式),现在推荐使用 Spring Cloud LoadBalancer。
  • Dubbo: Dubbo 框架自身内置了多种负载均衡策略。
  • gRPC: 需要结合外部负载均衡策略或自定义实现。
  • 自定义实现: 开发者可以基于 Nacos SDK 获取的实例列表自行实现负载均衡逻辑。

以下是集成 Nacos 后,客户端负载均衡器常用的策略:

  1. 轮询 (Round Robin):

    • 策略: 按顺序循环选择服务实例列表中的下一个实例。这是最基础的策略。
    • 实现: 维护一个内部计数器或索引,每次请求时递增(或取模),选择对应索引的实例。
    • Nacos 关联: 直接使用从 Nacos 获取的实例列表进行轮询。
  2. 随机 (Random):

    • 策略: 从服务实例列表中完全随机地选择一个实例。
    • 实现: 生成一个列表大小范围内的随机数,选择该随机数对应的实例。
    • Nacos 关联: 直接使用从 Nacos 获取的实例列表进行随机选择。
  3. 加权轮询 (Weighted Round Robin):

    • 策略: 类似于轮询,但每个实例被选中的次数与其在 Nacos 中配置的权重成正比。权重越高的实例会被轮询到更多次。
    • 实现: 常见的实现方式是根据权重构建一个扩展列表(例如权重为 2 的实例在列表中出现 2 次)然后进行简单轮询,或者使用更复杂的算法(如 Nginx 的平滑加权轮询)来避免短时间内请求集中在同一高权重实例。
    • Nacos 关联: 直接利用了 Nacos 实例的 weight 属性。这是 Nacos 权重特性最直接的应用场景。
  4. 加权随机 (Weighted Random):

    • 策略: 随机选择一个实例,但每个实例被选中的概率与其在 Nacos 中配置的权重成正比。权重越高的实例被选中的概率越大。
    • 实现: 计算所有实例的总权重 W。生成一个 0 到 W 之间的随机数 R。遍历实例列表,累加权重,当累加权重首次大于或等于 R 时,选择当前实例。
    • Nacos 关联: 同样利用了 Nacos 实例的 weight 属性。
  5. 响应时间加权 (Response Time Weighted - Ribbon 中有类似概念):

    • 策略: (此策略更多由 Ribbon 提供,Spring Cloud LoadBalancer 默认不直接提供,但可扩展) 基于实例的平均响应时间来分配权重,响应时间越短的实例获得更高的选中概率(或在轮询中获得更多机会)。
    • 实现: 负载均衡器需要持续统计每个实例的响应时间,并动态计算权重。
    • Nacos 关联: Nacos 本身不直接提供实时响应时间,需要负载均衡器自行收集。
  6. 最少连接/并发数 (Least Connections/Least Active - Dubbo 中常见):

    • 策略: (此策略在 Dubbo 中常见) 选择当前活动连接数或并发请求数最少的实例。认为连接越少的实例负载越低。
    • 实现: 负载均衡器需要跟踪每个实例的活动连接/请求计数。
    • Nacos 关联: Nacos 不提供实时连接数,需要框架或负载均衡器自行统计。

实现流程 (以 Spring Cloud LoadBalancer + Nacos 为例):

  1. 获取实例列表:

    • NacosServiceInstanceListSupplier (Spring Cloud LoadBalancer 与 Nacos 的集成点) 通过 Nacos Client SDK (NamingService) 从 Nacos Server 获取指定 serviceId 的健康实例列表 (List<Instance>)。这个过程利用了 Nacos 的服务发现能力(Pull + Push)。
  2. 缓存实例列表:

    • 获取到的实例列表通常会被缓存在 ServiceInstanceListSupplier 中,避免频繁查询 Nacos。Nacos 的 Push 机制会保证缓存在实例变更时得到更新。
  3. 触发负载均衡:

    • 当使用 @LoadBalanced RestTemplate 或 FeignClient 发起服务调用时,请求会被 Spring Cloud LoadBalancer 的拦截器 (如 LoadBalancerInterceptor) 截获。
  4. 选择实例:

    • 拦截器调用核心负载均衡逻辑 (如 RoundRobinLoadBalancer 或 RandomLoadBalancer,取决于配置)。
    • 负载均衡器从 ServiceInstanceListSupplier 获取当前的缓存实例列表。
    • 根据配置的策略(轮询、随机、或利用 Nacos 权重的加权策略),从列表中选择一个 ServiceInstance。
      • 对于加权策略,会读取 ServiceInstance 对象中携带的 Nacos 实例的 weight 值 (通常存储在 metadata 中,并被适配器转换为 ServiceInstance 的一部分)。
  5. 执行请求:

    • 拦截器使用选定 ServiceInstance 的 host 和 port 重新构建请求的 URL。
    • 将请求发送到选定的目标实例。

如何配置 (Spring Cloud):

通常在 application.yml 或 application.properties 中为特定的服务或全局配置负载均衡策略:

spring:
  cloud:
    loadbalancer:
      # 全局配置 (默认是轮询)
      # default-to-all: # Optional: Apply default policy to all services
      #   policy: random # Example: Set default to Random

      # 为特定服务配置
      clients:
        # service-provider-id 是要调用的服务名 (提供者的 spring.application.name)
        - id: service-provider-id
          # 可选值:round-robin, random (Spring Cloud LoadBalancer 默认支持这两种)
          # 如果集成了支持权重的扩展,可能有 weighted-random 或 weighted-round-robin 等
          policy: random # 为 service-provider-id 服务指定随机策略

总结:

  • Nacos 客户端本身不执行复杂的负载均衡,但提供了基础数据(实例列表、权重)。
  • 实际的负载均衡由集成的客户端负载均衡库(如 Spring Cloud LoadBalancer、Ribbon、Dubbo LoadBalance)负责。
  • 常见的策略包括轮询、随机、加权轮询、加权随机等。
  • Nacos 的实例权重 (weight) 是实现加权类负载均衡策略的关键输入。
  • 实现流程涉及:从 Nacos 获取实例 -> 缓存 -> 拦截请求 -> 根据策略选择实例 -> 发送请求。
  • 具体使用哪种策略以及如何配置,取决于你使用的技术栈和负载均衡库。
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐