Spring Cloud LoadBalancer 官方文档
介绍
Spring Cloud 提供了自己的客户端负载均衡器的抽象和实现. 目前已经支持的http客户端有:
- Spring
RestTemplate
as a LoadBalancer Client - Spring
RestClient
as a LoadBalancer Client - Spring
WebClient
as a LoadBalancer Client - Spring
WebFlux WebClient
withReactorLoadBalancerExchangeFilterFunction
已经提供的负载均衡算法有随机和轮询, 可以看到源码中 ReactorServiceInstanceLoadBalancer 接口的实现类:
实战
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
测试
这里使用RestTemplate来测试负载均衡效果, 默认均衡算法为轮询算法.
@GetMapping("/list")
public String getOrders() {
// 请求商品列表
// 1. 通过RestTemplate调用goods-svc服务的商品列表接口
String resp = restTemplate.getForObject("http://goods-svc/goods/list", String.class);
log.info(resp);
return resp;
}
原理
通过debug可以得知, 最终的实现原理是通过restTemplate拦截器 LoadBalancerInterceptor 切入负载均衡, 最终通过RoundRobinLoadBalancer#getInstanceResponse方法选择出来一个实例作为请求目标:
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + this.serviceId);
}
return new EmptyResponse();
} else if (instances.size() == 1) {
return new DefaultResponse((ServiceInstance)instances.get(0));
} else {
int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;
ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());
return new DefaultResponse(instance);
}
}
这里算法也很简单: 就是请求次数 % 实例数量
修改负载均衡算法
public class LoadBalancerConfiguration {
/**
* 修改负载均衡策略
* @param environment
* @param loadBalancerClientFactory
* @return
*/
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
@Configuration
@LoadBalancerClient(name = "goods-svc", configuration = LoadBalancerConfiguration.class)
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
总结
综上所述,Spring Cloud LoadBalancer 提供了灵活而强大的负载均衡功能,可以满足各种场景下的需求。