什么是 @LoadBalanced

@LoadBalanced 是 Spring Cloud 提供给 RestTemplateWebClient 等客户端的标记性注解(marker annotation),它的作用是:

开启客户端负载均衡(Client-Side Load Balancing)

📌 核心能力:

  • 将服务名(如 http://orderservice)解析为真实 IP + 端口
  • 从注册中心(如 Nacos、Eureka)获取服务实例列表
  • 按照负载均衡策略(如轮询、随机)选择一个实例
  • 自动完成 HTTP 请求的转发

核心原理:@LoadBalanced 如何工作?

1️⃣ 关键组件:LoadBalancerInterceptor

当你在 RestTemplate 上添加 @LoadBalanced 注解后,Spring Cloud 会自动为其注册一个 拦截器(Interceptor) —— LoadBalancerInterceptor

// 伪代码:拦截器逻辑
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) {// 1. 获取服务名(如 "userservice")URI originalUri = request.getURI();String serviceName = originalUri.getHost();// 2. 从 LoadBalancerClient 获取实例ServiceInstance instance = loadBalancerClient.choose(serviceName);// 3. 替换 URL 为真实地址URI newUri = URI.create(originalUri.toString().replace(serviceName, instance.getHost() + ":" + instance.getPort()));// 4. 执行真实请求return execution.execute(new Request(newUri, ...), body);
}

📌 本质
@LoadBalanced 并没有改变 RestTemplate 的发送逻辑,而是通过拦截 + URL 重写的方式实现负载均衡。

 实战:自定义负载均衡策略

场景:实现“同区域优先”调用(避免跨机房调用)

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import reactor.core.publisher.Mono;public class ZonePreferenceLoadBalancer implements ReactorServiceInstanceLoadBalancer {private final String localZone = "beijing"; // 本地机房@Overridepublic Mono<Response<ServiceInstance>> choose(Request request) {return Mono.fromCallable(() -> {// 获取服务名String serviceId = (String) request.getContext().getServiceKey();// 获取所有实例List<ServiceInstance> instances = LoadBalancerClientFactory.getInstances(serviceId);// 优先选择同区域实例List<ServiceInstance> preferred = instances.stream().filter(instance -> "beijing".equals(instance.getMetadata().get("zone"))).collect(Collectors.toList());if (!preferred.isEmpty()) {return new DefaultResponse(preferred.get(new Random().nextInt(preferred.size())));}// 否则选择任意实例return new DefaultResponse(instances.get(new Random().nextInt(instances.size())));}).onErrorReturn(new EmptyResponse());}
}

注册自定义策略

@Configuration
public class LoadBalancerConfig {@Bean@ConditionalOnMissingBeanpublic ReactorServiceInstanceLoadBalancer zonePreferenceLoadBalancer(LoadBalancerClientFactory clientFactory) {String serviceId = clientFactory.get().getName();return new ZonePreferenceLoadBalancer();}
}

不要把 @LoadBalanced 当作“魔法注解”。理解其背后的设计思想,才能在复杂场景中游刃有余。它是 Spring Cloud 客户端负载均衡的基石,也是你掌握微服务调用链路的关键一环。