什么是 @LoadBalanced
?
@LoadBalanced
是 Spring Cloud 提供给 RestTemplate
、WebClient
等客户端的标记性注解(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"; // 本地机房
@Override
public 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
@ConditionalOnMissingBean
public ReactorServiceInstanceLoadBalancer zonePreferenceLoadBalancer(
LoadBalancerClientFactory clientFactory) {
String serviceId = clientFactory.get().getName();
return new ZonePreferenceLoadBalancer();
}
}
不要把 @LoadBalanced
当作“魔法注解”。理解其背后的设计思想,才能在复杂场景中游刃有余。它是 Spring Cloud 客户端负载均衡的基石,也是你掌握微服务调用链路的关键一环。