LoadBalancer 和 Ribbon 的区别是什么?为什么用它替代 Ribbon?

一则或许对你有用的小广告

欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于 Spring AI + Spring Boot3.x + JDK 21...点击查看;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot3.x + JDK 17...点击查看项目介绍; 演示链接: http://116.62.199.48:7070/;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/

面试考察点

面试官提出这个问题,通常意在考察以下几点:

  1. 对 Spring Cloud 微服务生态演进的理解:你是否了解 Netflix 组件进入维护模式这一背景,以及 Spring Cloud 官方应对策略。
  2. 对不同客户端负载均衡组件核心原理的掌握:不仅仅要知道它们是什么,更要理解其底层机制和设计差异。
  3. 技术选型与架构决策能力:面对新旧技术更替,能否从功能性、可维护性、社区活跃度与生态的整合度等多个维度进行理性分析,而不仅仅是知道“哪个是新的”。
  4. 对新技术的接纳与实际应用经验:是否有跟进 Spring Cloud 最新技术栈,并理解 LoadBalancer 带来的新特性(如响应式编程支持)。

核心答案

这里的 LoadBalancer 特指 Spring Cloud LoadBalancer,它是 Spring Cloud 官方在 2020 年推出的,用于替代 Netflix Ribbon 的客户端负载均衡器

主要区别与替代原因如下:

  1. 出身与维护状态:Ribbon 是 Netflix 开源的项目,已进入维护模式,不再添加新功能。Spring Cloud LoadBalancer 是 Spring Cloud 官方项目,是其未来微服务生态的核心组件,持续活跃更新。
  2. 依赖与整合:Ribbon 强依赖 Netflix 的其他组件(如 Eureka)。Spring Cloud LoadBalancer 设计为与 Spring Cloud 解耦,可以更灵活地与任何服务发现(如 Nacos, Consul)或注册中心协同工作,是 Spring Cloud Commons 抽象的标准实现。
  3. 编程模型支持:Spring Cloud LoadBalancer 原生支持响应式编程模型(基于 Project Reactor),为 Spring WebFluxReactive 应用提供了无缝的负载均衡能力,而 Ribbon 主要服务于传统的同步阻塞式应用。
  4. 配置与扩展性:LoadBalancer 提供了更现代化、灵活的配置方式(如基于 @LoadBalancerClient 注解或 LoadBalancerBuilder),其 SPI(服务提供者接口)设计更易于自定义负载均衡算法和逻辑。

简单来说,Spring Cloud 用官方自研的 Spring Cloud LoadBalancer 替代了已停止演进的 Netflix Ribbon,旨在提供更轻量、更灵活、更好融入 Spring 响应式生态且由官方长期维护的客户端负载均衡解决方案。

深度解析

原理与机制

  • Ribbon:核心是一个基于 IRuleIPing 接口的客户端负载均衡器。它在客户端维护了一份从服务发现中心(如 Eureka)获取的服务实例列表,并通过内置的轮询、随机等规则选择一个实例发起调用。其内部大量使用了线程池和阻塞 I/O。
  • Spring Cloud LoadBalancer:它的核心接口是 ReactiveLoadBalancerServiceInstanceListSupplier。它通过 WebClientRestTemplate 的拦截器机制工作。其默认实现也提供了 RoundRobinLoadBalancerRandomLoadBalancer 等策略。更重要的是,它的响应式实现是基于 事件驱动和非阻塞 I/O 的。

代码示例 - 使用方式

// 1. 使用 Spring Cloud LoadBalancer 配合 WebClient (响应式)
@Bean
@LoadBalanced // 这个注解现在背后已经是 LoadBalancer 了
public WebClient.Builder loadBalancedWebClientBuilder() {
    return WebClient.builder();
}

// 在服务中注入并使用
@Service
public class MyService {
    @Autowired
    private WebClient.Builder webClientBuilder;

    public Mono<String> callOtherService() {
        return webClientBuilder.build()
                .get()
                .uri("http://my-service/api/resource") // 使用服务名而非具体IP
                .retrieve()
                .bodyToMono(String.class);
    }
}

// 2. 自定义负载均衡策略 (例如,始终选择第一个实例)
@Configuration
public class MyLoadBalancerConfig {
    @Bean
    public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(
            Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(
                loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),
                name
        );
        // 你可以在这里返回任何自定义的 LoadBalancer 实现
    }
}

最佳实践与注意事项

  • 新项目:如果使用 Spring Cloud 2020.x (Ilford) 及以后版本,应直接使用 Spring Cloud LoadBalancer,它是默认且唯一的内置选择。
  • 旧项目迁移:对于仍在使用 Ribbon 的老项目,如果稳定运行且无响应式需求,不一定需要立即迁移。但若计划升级 Spring Cloud 大版本(例如到 2020.x+),则必须迁移,因为该版本后已彻底移除 Ribbon 支持。
  • 功能对照:LoadBalancer 已覆盖 Ribbon 的核心功能(如区域亲和性 Zone Affinity)。对于 Ribbon 的一些高级特性(如 ServerListFilter 的精细控制),需通过 LoadBalancer 的 SPI 接口自行实现。

常见误区

  • 误区一:认为 LoadBalancer 是远程的 “负载均衡服务器”。它和 Ribbon 一样,都是嵌入在客户端应用内部的库。
  • 误区二:认为 LoadBalancer 性能一定远超 Ribbon。在同步阻塞场景下,两者性能差异不大。LoadBalancer 的主要优势在于架构先进性(响应式支持、维护状态)和与 Spring 生态的深度整合
  • 误区三:忽略了 spring-cloud-starter-loadbalancer 依赖。从 Spring Cloud 2020 开始,即使使用 @LoadBalanced,也必须显式引入此依赖,否则负载均衡功能将不生效。

总结

Spring Cloud LoadBalancer 是 Spring 官方为拥抱响应式编程和构建更自主的微服务生态而推出的 Ribbon 替代品,其替代的核心驱动力源于技术栈的可持续维护性、架构现代化以及生态整合的主动权