什么是 @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"; // 本地机房@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 客户端负载均衡的基石,也是你掌握微服务调用链路的关键一环。