介绍
Spring Cloud 提供了自己的客户端负载均衡器的抽象和实现. 目前已经支持的http客户端有:
已经提供的负载均衡算法有随机和轮询, 可以看到源码中 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 提供了灵活而强大的负载均衡功能,可以满足各种场景下的需求。