Spring Cloud LoadBalancer(SCLB)是 Spring Cloud 官方提供的客户端负载均衡器,替代了老旧的 Ribbon(已停止维护)。它的核心价值是:在微服务架构中,客户端(如订单服务)调用其他服务(如库存服务)时,自动从服务注册中心(Nacos/Eureka)获取服务实例列表,通过负载均衡算法选择一个实例发起请求,实现「服务集群的负载分发」和「故障自动切换」。
本文基于 Spring Cloud Alibaba 环境(适配 Nacos 服务发现),从「入门配置→核心功能→进阶实战→生产优化」逐步讲解,帮你快速掌握 LoadBalancer 的使用。
一、入门:快速集成(5 分钟上手)
1. 核心依赖(无需额外引入,已包含在常用 Starter 中)
在微服务客户端(如 order-server)的 pom.xml 中,只要引入了 spring-cloud-starter-alibaba-nacos-discovery 或 spring-cloud-starter-openfeign,会自动依赖 LoadBalancer 核心包(Spring Cloud 2020+ 版本默认集成):
<!-- Nacos 服务发现(自动依赖 LoadBalancer) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- OpenFeign(自动依赖 LoadBalancer,用于服务间调用) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 基础配置(application.yml)
无需额外配置,LoadBalancer 会自动与 Nacos 集成,从注册中心拉取服务实例。核心配置仅需确保「服务发现启用」:
spring:
application:
name: order-server # 当前服务名
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 注册中心地址
# LoadBalancer 可选配置(默认无需配置,使用默认算法)
loadbalancer:
# 禁用缓存(开发环境用,生产环境建议启用)
cache:
enabled: false
# 连接超时(默认 1000ms)
client:
connect-timeout: 2000
# 读取超时(默认 5000ms)
read-timeout: 6000
3. 两种使用场景(Feign 调用 + RestTemplate 调用)
LoadBalancer 支持两种客户端调用方式,均会自动触发负载均衡:
(1)场景 1:OpenFeign 调用(推荐,微服务主流方式)
Feign 是声明式 HTTP 客户端,与 LoadBalancer 无缝集成,无需手动处理负载均衡逻辑:
- 步骤 1:启动类添加
@EnableFeignClients注解,启用 Feign:@SpringBootApplication @EnableDiscoveryClient // 启用 Nacos 服务发现 @EnableFeignClients // 启用 Feign 客户端 public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } } - 步骤 2:定义 Feign 接口(指定目标服务名
stock-server):import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // name = 目标服务名(必须与 Nacos 中注册的服务名一致) @FeignClient(name = "stock-server") public interface StockFeignClient { // 对应 stock-server 的接口路径和参数 @GetMapping("/stock/deduct/{productId}") String deductStock(@PathVariable("productId") Long productId); } - 步骤 3:在业务代码中注入 Feign 接口,直接调用(自动负载均衡):
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class OrderController { @Resource private StockFeignClient stockFeignClient; @GetMapping("/order/create/{productId}") public String createOrder(@PathVariable Long productId) { // 调用 stock-server,LoadBalancer 自动选择实例 String stockResult = stockFeignClient.deductStock(productId); return "订单创建成功!" + stockResult; } }
(2)场景 2:RestTemplate 调用(手动配置)
若不使用 Feign,可通过 @LoadBalanced 注解标记 RestTemplate,使其具备负载均衡能力:
- 步骤 1:配置 RestTemplate 并添加
@LoadBalanced:import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean @LoadBalanced // 关键:启用 LoadBalancer 负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } } - 步骤 2:业务代码中使用 RestTemplate 调用(URL 填写服务名,而非 IP: 端口):
@RestController public class OrderController { @Resource private RestTemplate restTemplate; @GetMapping("/order/create/{productId}") public String createOrder(@PathVariable Long productId) { // 注意:URL 中用服务名 stock-server 替代 IP:端口 String url = "http://stock-server/stock/deduct/" + productId; // LoadBalancer 自动解析服务名,选择实例转发 String stockResult = restTemplate.getForObject(url, String.class); return "订单创建成功!" + stockResult; } }
4. 测试验证
- 启动 Nacos 注册中心;
- 启动 2 个
stock-server实例(端口分别为 8020、8021,服务名均为stock-server); - 启动
order-server,多次访问http://localhost:8010/order/create/1; - 观察
stock-server的日志,会发现两个实例交替接收请求(默认轮询算法)。
二、核心概念:负载均衡算法(默认 + 自定义)
LoadBalancer 的核心是「负载均衡算法」,即如何从服务实例列表中选择一个实例。Spring Cloud LoadBalancer 提供了默认算法,也支持自定义扩展。
1. 内置默认算法(无需配置,开箱即用)
| 算法类型 | 适用场景 | 原理 |
|---|---|---|
| RoundRobinLoadBalancer(轮询) | 所有实例性能相近,无明显差异 | 按实例顺序依次选择(实例 1→实例 2→实例 1→实例 2...),默认使用该算法。 |
| RandomLoadBalancer(随机) | 希望请求随机分发,避免单一实例压力集中 | 从实例列表中随机选择一个实例。 |
| ResponseTimeWeightedLoadBalancer(响应时间加权) | 实例性能差异较大(如部分实例配置更高) | 响应时间越短的实例,被选中的概率越高(需引入 spring-boot-starter-actuator 收集响应时间)。 |
切换默认算法(配置文件方式)
在客户端(如 order-server)的 application.yml 中配置,指定全局默认算法:
spring:
cloud:
loadbalancer:
# 切换为随机算法(可选值:round_robin、random、response_time_weighted)
nimbus:
rule: random
2. 自定义负载均衡算法(实战场景)
实际项目中,可能需要根据业务场景自定义算法(如「权重负载均衡」「区域亲和性负载均衡」)。以下以「权重算法」为例,讲解自定义步骤:
需求:给不同的 stock-server 实例配置不同权重,权重越高,被选中的概率越大
-
步骤 1:给
启动stock-server实例配置权重(在 Nacos 中设置元数据):stock-server时,通过启动参数指定权重(或在application.yml中配置):spring: cloud: nacos: discovery: server-addr: 127.0.0.1:8848 metadata: weight: 5 # 实例1权重为5(端口8020)
若另一个实例配置 weight: 10(端口 8021),权重比为 1:2。
-
步骤 2:自定义负载均衡规则(实现
ReactorServiceInstanceLoadBalancer接口):import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.*; import org.springframework.cloud.loadbalancer.core.NoopServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import reactor.core.publisher.Mono; import java.util.List; import java.util.Random; import java.util.stream.Collectors; /** * 自定义权重负载均衡算法 */ public class WeightedLoadBalancer implements ReactorServiceInstanceLoadBalancer { private final String serviceId; // 目标服务名 private final Random random; // 随机数生成器 public WeightedLoadBalancer(String serviceId) { this.serviceId = serviceId; this.random = new Random(); } @Override public Mono<Response<ServiceInstance>> choose(Request request) { // 1. 获取服务实例列表(从 Nacos 拉取) ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier.builder() .withServiceId(serviceId) .build(); return supplier.get() .next() .map(this::selectInstanceByWeight); } /** * 按权重选择实例 */ private Response<ServiceInstance> selectInstanceByWeight(List<ServiceInstance> instances) { if (instances.isEmpty()) { return new EmptyResponse(); } // 2. 过滤出有权重配置的实例(权重≥1) List<ServiceInstance> validInstances = instances.stream() .filter(instance -> { String weightStr = instance.getMetadata().get("weight"); return weightStr != null && Integer.parseInt(weightStr) > 0; }) .collect(Collectors.toList()); if (validInstances.isEmpty()) { return new EmptyResponse(); } // 3. 计算总权重 int totalWeight = validInstances.stream() .mapToInt(instance -> Integer.parseInt(instance.getMetadata().get("weight"))) .sum(); // 4. 生成随机数,按权重区间选择实例 int randomNum = random.nextInt(totalWeight); int currentWeight = 0; for (ServiceInstance instance : validInstances) { currentWeight += Integer.parseInt(instance.getMetadata().get("weight")); if (randomNum < currentWeight) { return new DefaultResponse(instance); } } // 兜底:返回第一个实例 return new DefaultResponse(validInstances.get(0)); } } -
步骤 3:配置自定义算法为全局默认规则:
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @Configuration public class LoadBalancerConfig { /** * 注册自定义权重负载均衡算法 */ @Bean public ReactorLoadBalancer<ServiceInstance> weightedLoadBalancer( Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { // 获取目标服务名(从环境变量中读取) String serviceId = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); return new WeightedLoadBalancer(serviceId); } } -
步骤 4:测试验证:启动 2 个
stock-server实例(权重 5 和 10),多次访问order-server接口,会发现权重 10 的实例被调用的概率是权重 5 的 2 倍。
三、进阶:核心功能实战(生产必备)
1. 实例健康检查(故障自动剔除)
LoadBalancer 支持「健康检查」,当服务实例不可用时(如宕机、接口报错),自动从实例列表中剔除,避免请求转发到故障实例。
(1)基于 Nacos 健康检查(推荐,无需额外配置)
Nacos 自带服务健康检查机制(默认心跳检测,每 5 秒发送一次心跳),当实例宕机或心跳超时,Nacos 会将其标记为「不健康」,LoadBalancer 从 Nacos 拉取实例时,只会获取「健康实例」。
(2)自定义健康检查(针对接口级健康状态)
若需要更精细的健康检查(如检查实例的 /health 接口是否正常),可集成 Spring Boot Actuator:
- 步骤 1:添加 Actuator 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> - 步骤 2:配置 Actuator 暴露健康端点:
management: endpoints: web: exposure: include: health # 暴露 /actuator/health 端点 endpoint: health: show-details: always # 显示健康详情 - 步骤 3:LoadBalancer 自动关联健康检查(无需额外配置):当实例的
/actuator/health端点返回DOWN时,LoadBalancer 会将其剔除,直到端点返回UP才重新加入实例列表。
2. 负载均衡缓存(提升性能)
LoadBalancer 会缓存服务实例列表,避免每次调用都从 Nacos 拉取(减少网络开销)。生产环境建议启用缓存,并配置合理的缓存过期时间:
spring:
cloud:
loadbalancer:
cache:
enabled: true # 启用缓存(默认 false)
ttl: 30000 # 缓存过期时间(30秒,默认 30 秒)
# 缓存键生成器(默认按服务名缓存,可自定义)
cache-key-generator:
type: org.springframework.cloud.loadbalancer.core.DefaultCacheKeyGenerator
3. 重试机制(失败自动重试)
当调用某个实例失败时(如网络超时、接口报错),LoadBalancer 支持自动重试到其他健康实例,提升系统可用性。需配合 spring-retry 依赖实现:
- 步骤 1:添加重试依赖:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> - 步骤 2:配置重试规则(application.yml):
spring: cloud: loadbalancer: retry: enabled: true # 启用重试(默认 false) max-retries-on-next-service: 1 # 切换到下一个实例的重试次数(默认 1) max-retries-on-same-service-instance: 0 # 同一实例的重试次数(默认 0,避免重复调用同一实例) - 步骤 3:Feign 中启用重试(可选,Feign 自带重试机制):
feign: retry: enabled: true # 启用 Feign 重试(默认 false) max-attempts: 3 # 最大重试次数(包括首次调用) period: 1000 # 重试间隔(1秒) max-period: 3000 # 最大重试间隔(3秒)
4. 针对特定服务配置独立负载均衡规则
全局规则会作用于所有服务调用,若需要给某个服务(如 stock-server)配置独立规则(如随机算法),其他服务仍用默认轮询算法,可通过「服务级配置」实现:
- 步骤 1:创建服务级配置类(注意:该类不能被
@ComponentScan扫描到,否则会变成全局规则):import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer; import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; // 注意:该类无需添加 @Configuration 到主启动类的扫描路径(可放在单独包下) @Configuration public class StockServiceLoadBalancerConfig { @Bean public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer( Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String serviceId = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); // 给 stock-server 配置随机算法 return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class), serviceId); } } - 步骤 2:在 Feign 接口中指定该配置类:
import org.springframework.cloud.openfeign.FeignClient; // configuration = 指定服务级负载均衡配置类 @FeignClient(name = "stock-server", configuration = StockServiceLoadBalancerConfig.class) public interface StockFeignClient { // 接口方法... } - 效果:调用
stock-server时使用随机算法,调用其他服务(如user-server)仍使用全局默认轮询算法。
四、生产环境优化与最佳实践
1. 性能优化技巧
- 启用实例缓存:减少 Nacos 调用次数,提升响应速度;
- 合理配置超时时间:避免因实例响应缓慢导致客户端阻塞(建议
connect-timeout=2000ms,read-timeout=5000ms); - 禁用不必要的健康检查:若 Nacos 心跳检测已满足需求,可无需额外启用 Actuator 健康检查;
- 选择合适的负载均衡算法:性能相近的实例用轮询,性能差异大用响应时间加权,需要精准控制用权重算法。
2. 高可用配置
- 服务实例集群部署:至少部署 2 个实例,避免单点故障;
- 启用重试机制:确保故障实例能自动切换到健康实例;
- 配置实例隔离:通过 Nacos 命名空间或分组,将不同环境(开发 / 测试 / 生产)的服务实例隔离,避免跨环境调用。
3. 监控与排查
- 集成 Prometheus + Grafana:监控 LoadBalancer 的实例选择情况、缓存命中率、重试次数等指标;
- 开启 Debug 日志:排查负载均衡相关问题(如实例未被选中、重试未触发):
yaml
logging: level: # LoadBalancer 核心日志(DEBUG 级别) org.springframework.cloud.loadbalancer: DEBUG # Nacos 服务发现日志(DEBUG 级别) com.alibaba.cloud.nacos.discovery: DEBUG
4. 常见问题排查
(1)负载均衡不生效(请求只转发到一个实例)
- 检查服务名是否正确:Feign 接口
@FeignClient(name)必须与 Nacos 中注册的服务名一致(大小写敏感); - 检查实例是否健康:Nacos 控制台查看实例是否为「健康」状态;
- 检查缓存是否启用:开发环境若禁用缓存,需确保每次调用都能拉取最新实例列表。
(2)重试机制不生效
- 检查是否引入
spring-retry依赖; - 确认重试配置是否正确(
spring.cloud.loadbalancer.retry.enabled=true); - 检查异常类型:重试仅对「可重试异常」生效(如网络超时、连接拒绝,业务异常如
500不会重试)。
(3)实例健康但未被选中
- 检查实例缓存是否过期:若启用缓存,实例状态更新后需等待缓存过期(默认 30 秒);
- 检查负载均衡规则:是否因算法逻辑导致实例未被选中(如权重算法中权重配置为 0);
- 检查网络连通性:客户端是否能正常访问实例的 IP: 端口(排除防火墙、网络隔离问题)。
五、总结
Spring Cloud LoadBalancer 是微服务客户端负载均衡的核心组件,具有「轻量、易集成、可扩展」的特点,与 Spring Cloud Alibaba 生态(Nacos、Feign、Sentinel)无缝兼容。
学习路径建议:
- 入门:掌握 Feign + LoadBalancer 快速集成,实现基础负载均衡;
- 进阶:理解内置算法,实现自定义算法(如权重),配置健康检查和重试;
- 生产:优化缓存、超时、重试参数,结合监控工具保障高可用。
最佳实践:在微服务架构中,优先使用「Feign + LoadBalancer」组合实现服务间调用,配合 Nacos 服务发现和 Sentinel 限流熔断,打造稳定、高效的服务调用链路。
168万+

被折叠的 条评论
为什么被折叠?



