Spring Cloud LoadBalancer 最佳实践

Ribbon 曾经是 Spring Cloud 家族默认的客户端负载均衡工具,而 Spring Cloud LoadBalancer (SCLB) 是官方替换 Ribbon 的新实现。表面上它们都解决 “服务调用时选哪个实例” 的问题,但在理念、架构和生态上差异不小。


一、Ribbon  vs  SCLB


1. 定位和生态地位

  • Ribbon

    • Netflix OSS 出品,老一代的客户端负载均衡器。

    • 在 Spring Cloud Dalston ~ Greenwich 时代是默认选择。

    • 后来 Netflix OSS 宣布 进入维护模式(2018年起不再活跃发展)

  • Spring Cloud LoadBalancer

    • Spring 团队自研,替代 Ribbon。

    • 完全独立于 Netflix 生态,不再依赖过时组件。

    • 与 Spring Boot 2.x/3.x、Reactor、WebClient、Feign 等深度集成。


2. 核心设计思路

  • Ribbon

    • 侵入性较强:依赖 IClientConfigIRuleIPing 等接口,配置体系复杂。

    • 强调“策略类 + 配置类”模式(比如 RoundRobinRule、ZoneAvoidanceRule)。

    • 同步调用模型为主,虽然可扩展但偏“重量级”。

    • RestTemplate 深度耦合(通过 @LoadBalanced RestTemplate)。

  • Spring Cloud LoadBalancer

    • 函数式 + 轻量化:核心是 ServiceInstanceListSupplier(负责提供实例列表)和 ReactorServiceInstanceLoadBalancer(负责挑选实例)。

    • 完全 Reactor 化,支持响应式编程(Reactor/Flux/Mono),天然适配 WebClient。

    • API 更简单,默认策略是 RoundRobin,但很容易定制。

    • 更解耦,和 DiscoveryClient、Feign、gRPC 等可自由组合。


3. 扩展能力

  • Ribbon

    • 有比较多的现成策略:RoundRobinRuleRandomRuleRetryRuleWeightedResponseTimeRule

    • 自定义需要继承 IRule,配置也要绕 Ribbon 的专用配置体系。

    • 支持 Zone 概念(跨机房/多可用区),适合 Netflix 内部环境,但在普通企业里很少用上。

  • Spring Cloud LoadBalancer

    • 策略很“干净”:只要实现 ReactorServiceInstanceLoadBalancer 接口即可。

    • ServiceInstanceListSupplier 提供了天然的 hook:你可以在实例列表进入负载均衡前加上 过滤、排序、权重

    • 没有 Ribbon 那种内置十几个策略的复杂度,但用组合的方式,灵活度更高。


4. 与 Spring 生态的关系

  • Ribbon

    • 被强绑定到 RestTemplate + Feign(老版本)。

    • Spring Cloud Netflix 维护成本高,升级阻力大。

  • Spring Cloud LoadBalancer

    • 未来路线核心组件,和 Spring Cloud Gateway、Feign 3.x、WebClient 全兼容。

    • 官方推荐替代方案,Ribbon 已经标记 Deprecated

    • 随 Spring Boot/Spring Cloud 版本更新,能持续获得支持。


5. 性能与现代化

  • Ribbon

    • 基于老旧同步模型(虽然功能全,但显得笨重)。

    • 没有天然的 Reactor 支持,在响应式场景里不合拍。

  • Spring Cloud LoadBalancer

    • 基于 Reactor,轻量、非阻塞,天然适合高并发场景。

    • 使用 Flux<ServiceInstance>,可以灵活叠加缓存、权重、健康检查逻辑。

    • 更加云原生,能和 Kubernetes Service、Consul、Nacos 等平滑对接。


二、源码说明

1. 核心抽象

  • Ribbon

    • 结果:实例获取、缓存、负载均衡策略,全都绑死在 Ribbon 的体系

    • 负载均衡器接口:ILoadBalancer
      内部维护实例列表(ServerList),并交给 IRule 挑选。

    • 负载均衡策略接口:IRule

      public interface IRule {Server choose(Object key);void setLoadBalancer(ILoadBalancer lb);ILoadBalancer getLoadBalancer();
      }

      代表“从一堆服务实例里挑一个”。

    • Spring Cloud LoadBalancer (SCLB)

      • 实例供应接口:

        public interface ServiceInstanceListSupplier extends Supplier<Flux<List<ServiceInstance>>> {String getServiceId();
        }

        负责“提供候选实例列表”,来源可以是 DiscoveryClient、缓存、静态配置。

      • 策略接口:

        public interface ReactorServiceInstanceLoadBalancer {Mono<Response<ServiceInstance>> choose(Request request);
        }

        专注于“如何从候选列表里挑一个”。

      • 结果:候选列表与选择逻辑完全解耦,职责单一,而且基于 Reactor(非阻塞)。


2. Spring Cloud LoadBalancer 和 Feign 相对 Ribbon 的解耦性

看源码上的调用链对比最明显:

  • Ribbon + Feign
    Feign 的 LoadBalancerFeignClient → 直接调用 RibbonLoadBalancerClient → 使用 ILoadBalancer + IRule 绑定。

    public class RibbonLoadBalancerClient implements LoadBalancerClient {@Overridepublic ServiceInstance choose(String serviceId) {ILoadBalancer loadBalancer = getLoadBalancer(serviceId);Server server = loadBalancer.chooseServer(null);return new RibbonServer(serviceId, server, isSecure(server), serverIntrospector(serviceId).getMetadata(server));}
    }

    可以看到:Feign 和 Ribbon 耦合紧密ILoadBalancerIRule 必须都存在。

  • SCLB + Feign(Spring Cloud 2020+)
    Feign 的 LoadBalancerFeignClient → 使用 BlockingLoadBalancerClientReactorLoadBalancerExchangeFilterFunction

    public class BlockingLoadBalancerClient implements LoadBalancerClient {private final LoadBalancerClientFactory clientFactory;@Overridepublic ServiceInstance choose(String serviceId) {ReactorServiceInstanceLoadBalancer loadBalancer = clientFactory.getInstance(serviceId, ReactorServiceInstanceLoadBalancer.class);// 核心是调用 loadBalancer.choose()}
    }

    这里的关键:

    • Feign 只依赖于 ReactorServiceInstanceLoadBalancer 抽象,而不关心实例供应如何实现。

    • ServiceInstanceListSupplier 可随时替换(比如 Kubernetes、Consul、Nacos),Feign 本身无需改动。

👉 结论:Ribbon 时代 Feign 直接依赖 Ribbon 核心接口,导致强绑定;SCLB 下 Feign 只依赖于统一的 LoadBalancer 抽象,而实例来源和策略完全可插拔 → 解耦性更高


三、Spring Cloud LoadBalancer 最佳实践

1. 基础使用

引入依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

RestTemplate / WebClient 集成

@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.build();
}@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {return WebClient.builder();
}

建议优先用 WebClient,因为它能发挥 SCLB 的 Reactor 非阻塞优势。


2. 缓存与性能优化

SCLB 默认每次请求会调用 DiscoveryClient 获取实例,可以用内置的 缓存供应器

@Bean
public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(ConfigurableApplicationContext context) {return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching() // 启用缓存.build(context);
}

这样能减少注册中心压力,尤其是在高并发场景。


3. 自定义策略

简单示例:基于元数据的优先级选择

比如实例 metadata 里有 "zone": "shanghai",只要优先调用同城实例:

@Bean
ReactorServiceInstanceLoadBalancer zoneAwareLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> supplierProvider) {return new ReactorServiceInstanceLoadBalancer() {@Overridepublic Mono<Response<ServiceInstance>> choose(Request request) {return supplierProvider.getIfAvailable().get().next().map(instances -> {List<ServiceInstance> localZone = instances.stream().filter(i -> "shanghai".equals(i.getMetadata().get("zone"))).toList();if (!localZone.isEmpty()) {return new DefaultResponse(localZone.get(0));}return new DefaultResponse(instances.get(0));});}};
}

更复杂:权重路由

实现 ReactorServiceInstanceLoadBalancer,结合 metadata.weight 字段,做加权随机选择。这相当于 Ribbon 的 WeightedResponseTimeRule,但在 SCLB 里更灵活。


4. ServiceInstanceListSupplier 增强

SCLB 提供了“供应链”思想,常用扩展点:

  • 过滤:过滤掉 metadata 标记为 "status=down" 的实例;

  • 排序:按响应时间/CPU负载排序,把健康的放前面;

  • 包装:组合多层供应器(比如先 DiscoveryClient → 再缓存 → 再 zone 过滤)。

这种链式增强比 Ribbon 的配置类清晰得多。


5. 与 Feign 配合

在新版 Spring Cloud 中,Feign 默认走 SCLB。最佳实践:

  • 配置 spring.cloud.loadbalancer.retry.enabled=true → 自动开启重试机制;

  • 自定义 ReactorServiceInstanceLoadBalancer,Feign 会自动走你的策略;

  • 如果想做更细粒度控制,可以写 @FeignClient(configuration=...) 指定独立的 LoadBalancer 配置。


6. 容错与重试

SCLB 不再像 Ribbon 那样内置 RetryRule,而是把重试交给 Spring Retry

spring:cloud:loadbalancer:retry:enabled: trueretry-on-all-operations: truemax-retries-on-same-service-instance: 1max-retries-on-next-service-instance: 2

这样能保证单实例失败 → 自动切换下一个实例,避免单点问题。


7. 云原生环境最佳实践

  • Kubernetes 上,推荐直接基于 spring-cloud-starter-kubernetes-client + SCLB,实例供应就是 Pod 列表;

  • Nacos / Consul 场景下,直接使用对应 DiscoveryClient starter,SCLB 自动适配;

  • 保持 ServiceInstance metadata 丰富(zone、weight、tag),方便做策略。


8. 迁移建议(Ribbon → SCLB)

  • RestTemplate 上的 @LoadBalanced 不需要动,底层自动切换为 SCLB;

  • Feign 默认走 SCLB,不需要额外改动;

  • Ribbon 自定义的 IRule 策略,需要改写成 ReactorServiceInstanceLoadBalancer

  • Ribbon 的 Zone/Weight 逻辑,迁移到 ServiceInstanceListSupplier + metadata 策略更清晰。


总结

最佳实践关键就是 “解耦 + 插拔”

  • 实例来源 → DiscoveryClient + 缓存

  • 实例增强 → Supplier 过滤/排序/权重

  • 策略 → 自定义 LoadBalancer

  • 调用 → WebClient / Feign

  • 容错 → Spring Retry

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919325.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【STM32】SPI 与 Flash 笔记

1️⃣ SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;英文解释&#xff1a; Serial&#xff1a;串行Peripheral&#xff1a;外设Interface&#xff1a;接口用途&#xff1a;MCU 与外部设备&#xff08;Flash、传感器等&#xff09;高速数据通…

抽象工厂设计模式 Abstract Factory

抽象工厂抽象工厂设计模式是一种创建模式&#xff0c;它提供了一个用于创建相关或从属对象族的接口&#xff0c;而无需指定其具体类。 它在以下情况下特别有用&#xff1a; 您需要创建必须一起使用并且是一致系列的一部分的对象&#xff08;例如&#xff0c;按钮、复选框和菜单…

WSL 下的虚拟网卡配置

第一部分&#xff1a;Windows 虚拟网卡创建指南 1. 原理 在 Windows 里&#xff0c;“虚拟网卡”本质是由网络驱动在系统网络栈中创建的一个 软件网卡接口。它的作用和物理网卡类似&#xff0c;只不过不直接连接到物理硬件&#xff0c;而是通过内核网络驱动与宿主机网络进行交换…

Dify web前端源码本地部署详细教程

目录 1. 先启动API 2. 启动worker服务 3. 启动web 4. 访问登陆地址 在前面的文章中&#xff0c;Dify源码部署&#xff0c;搭建二次开发环境&#xff08;一&#xff09; 已经记录了如何在本地启动API、work、中间件。在本篇文章中&#xff0c;将概述如何启动dify web源码项…

CVPR 2025|英伟达联合牛津大学提出面向3D医学成像的统一分割基础模型

在 2D 自然图像和视频的交互式分割领域&#xff0c;基础模型已引发广泛关注&#xff0c;这也促使人们开始构建用于医学成像的 3D 基础模型。然而&#xff0c;3D 医学成像存在的领域差异以及临床应用场景&#xff0c;要求开发一种有别于现有 2D 解决方案的专用模型。具体而言&am…

解决“Win7共享文件夹其他电脑网络无法发现共享电脑名称”的问题

要让运行 Windows 7 的电脑被局域网中其他设备&#xff08;包括另一台电脑、手机、NAS 等&#xff09;“发现”&#xff0c;必须同时满足三个条件&#xff1a; 网络发现功能已启用&#xff1b;对应的后台服务已启动&#xff1b;防火墙规则放行。 下面给出最简、最稳妥的 3 步设…

Python pyzmq 库详解:从入门到高性能分布式通信

一、前言 在现代软件开发中&#xff0c;进程间通信&#xff08;IPC&#xff09;与分布式系统通信已经成为基础能力。无论是构建一个微服务架构的后端&#xff0c;还是实现大规模并行计算任务&#xff0c;如何让不同的进程或节点之间高效地传递消息&#xff0c;都是核心问题。 传…

CentOS 7更换国内镜像源

第一步&#xff1a;检查系统版本 在修改任何配置之前&#xff0c;先确定你的 CentOS 版本&#xff0c;因为不同版本的镜像源配置文件不同。 cat /etc/redhat-release这个命令会显示你的 CentOS 版本信息&#xff0c;例如 CentOS Linux release 7.9.2009 (Core)。从你的错误日志…

详解 doclayout_yolo:Python 文档布局检测

目录一、doclayout_yolo 核心功能二、安装方法1. 直接安装2. 通过 PDF-Extract-Kit 安装三、使用示例1. 快速体验&#xff08;HuggingFace Demo&#xff09;2. 本地推理代码3. 批量处理四、技术亮点五、应用场景六、其他说明1.相关资源2. 注意事项doclayout_yolo 是一个基于 Y…

猫头虎AI分享|一款Coze、Dify类开源AI应用超级智能体Agent快速构建工具:FastbuildAI

猫头虎AI分享&#xff5c;一款 Coze、Dify 类开源 AI 应用超级智能体快速构建工具&#xff1a;FastbuildAI 区别在于它的易用度和商业闭环功能 摘要&#xff1a;FastbuildAI 是一个开源的 AI 应用“快速构建 商业化闭环”工具。它让个人开发者与小团队用 可视化 零代码 的方…

GitLab 安全漏洞 CVE-2025-6186 解决方案

本分分享极狐GitLab 补丁版本 18.2.2, 18.1.4, 18.0.6 的详细内容。这几个版本包含重要的缺陷和安全修复代码&#xff0c;我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS&#xff0c;技术团队已经进行了升级&#xff0c;无需用户采取任何…

【K8s】harbor安装与推送镜像

引言 在开发中&#xff0c;先推送镜像到docker&#xff0c;然后直接在docker运行。但是在K8S中&#xff0c;需要动态创建或者分配机器&#xff0c;这里需要将镜像推送到harbor仓库&#xff0c;然后再从仓库拉取到每台集群机器。 docker安装harbor&#xff1a;https://learnku…

FPGA读取AHT20温湿度模块思路及实现,包含遇到的问题(IIC协议)

一.阅读官方手册 手册在下方网址下载&#xff0c;该模块在各个网店平台均有销售 百度网盘 请输入提取码 手册重点关注IIC地址&#xff08;读地址0x71&#xff0c;写地址0x70&#xff09;、IIC命令和读写数据逻辑&#xff0c;手册写的比较简单&#xff08;感觉很多细节没到位…

项目会议怎么开才有效

要提高项目会议的有效性&#xff0c;需要做到以下几点&#xff1a;明确会议目的、制定具体的会议议程、合理控制会议时长、提前准备会议资料、选择合适的参会人员、设定清晰的会议目标、确保会议有决策和行动方案、会后及时跟进与落实。其中&#xff0c;明确会议目的尤为重要。…

计算机视觉第一课opencv(二)保姆级教

目录 简介 一、边界填充 1.函数说明 2.案例分析 二、图像运算 1.号运算 2.cv2.add()函数 3.图像加权运算 三、阈值处理 四、图像平滑处理 1.椒盐噪声 2.均值滤波&#xff08;Mean Filtering&#xff09; 3.方框滤波 4. 高斯滤波&#xff08;Gaussian Filtering&am…

母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南

> 在现代智能化养殖中,母猪姿态识别是健康监测的关键技术。本文将带你从0到1构建高精度母猪姿态识别系统,准确率可达95%以上! ## 一、为什么母猪姿态识别如此重要? 母猪的行为姿态是其健康状况的重要指标: - **站立姿态**:可能表示发情期或进食需求 - **侧卧姿态**:…

循序渐进学 Spring (下):从注解、AOP到底层原理与整合实战

文章目录7. 自动装配 (Autowiring)7.1 XML 自动装配7.2 使用注解实现自动装配Autowired vs Resource8. 使用注解开发&#xff08;完全体&#xff09;8.1 定义 Bean (Component 及其衍生注解)8.2 注入属性 (Value)8.3 注入对象8.4 定义作用域 (Scope)8.5 小结&#xff1a;XML vs…

C#WPF实战出真汁06--【系统设置】--餐桌类型设置

1、系统设置的基本概念系统设置是用于配置和管理餐桌类型和菜品类型&#xff0c;是维护整个系统的基础数据。通过系统设置&#xff0c;用户可以调整餐桌类型的添加&#xff0c;删除&#xff0c;编辑&#xff0c;分页&#xff0c;查询&#xff0c;重置&#xff0c;列表&#xff…

旋钮键盘项目---foc讲解(闭环位置控制)

hello&#xff0c;周六休息了一天&#xff0c;出去打本了。趁着夜色&#xff0c;花费了几个小时&#xff0c;也是将闭环代码写完&#xff0c;参考了灯哥的思路。接下来介绍一下我的整个流程&#xff1a; 一、闭环位置控制思路&#xff1a; 其实懂得了开环&#xff0c;那么闭环…

为什么有些相机“即插即用”,而有些则需要采集卡?

在工业生产中&#xff0c;工业相机是“眼睛”&#xff0c;它帮助我们看到世界&#xff0c;但你知道吗&#xff1f;不同的工业相机接口就像不同的“通道”&#xff0c;有些“通道”直接就能与计算机连接&#xff0c;而有些则需要一个额外的小配件——图像采集卡。那么&#xff0…