文章目录
- 前言
- 1. 背景
- spring-cloud-loadbalancer 的渊源
- 2. spring-cloud-loadbalancer 如何使用
- 3. 源码解析
- loadBalancer 负载均衡策略实现:
- 4. 和ribbon 比较
- 默认负载均衡比较
- 配置方面丰富性
- 5. 结论
- 参考
前言
spring-cloud-loadbalancer 实现负载均衡的原理与ribbon,也是代理,提供统一的负载均衡接口LoadBalancerClient
,对应的实现类是 BlockingLoadBalancerClient
。ribbon的实现类是 RibbonLoadBalancerClient
,详情参见 RestTemplate与Ribbon整合原理(基于spring-cloud-starter-alibaba-nacos-discovery、负载均衡)
1. 背景
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon
实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。
ribbon已经内置进好多微服务框架中了。
Spring Cloud Hoxton.M2 是第一个整合新的loadbalancer实现来替代Ribbon的版本。
Spring Cloud Hoxton.M2 is the first release containing both blocking and non-blocking load balancer client implementations as an alternative to Netflix Ribbon which has entered maintenance mode.
spring-cloud-loadbalancer 的渊源
- 2017年spring 开始尝试开发新的项目 spring-cloud-loadbalancer 替代ribbon,项目托管在
spring-cloud-incubator 孵化器
(多提一嘴,spring cloud alibaba 等顶级的项目大多从此孵化出来的,代表着 spring cloud 的发展方向) - 经过N个月的不维护,还以为spring 放弃此项目时,突然把此项目标记成归档迁移到spring-cloud-commons
- 发布2.2.0.M2 版本
2. spring-cloud-loadbalancer 如何使用
这里基于 最新的hoxton.m2 版本才可以使用,所以要配置spring的代理maven库:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.M2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencyManagement>
加入nacos-client ,使用 2.1.0版本,特别注意排除 ribbon依赖,不然loadbalancer 无效。
以spring-cloud-starter-alibaba-nacos-discovery为例,已经内置ribbon依赖,因此需要排除掉:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
加入 loadbalancer pom坐标,继承spring-cloud版本号:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
配置使用还是和 ribbon 一样配置,@LoadBalanced标记:
@Configuration
public class LbConfiguration {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
@GetMapping("/demo")
public String doOtherStuff() {
return restTemplate.getForObject("http://big-provider-server/demo", String.class);
}
3. 源码解析
核心类是BlockingLoadBalancerClient
目前版本只提供了 BlockingLoadBalancerClient 的实现, 注意看中文注释
// 删除只保留了核心代码注意
public class BlockingLoadBalancerClient implements LoadBalancerClient {
@Override
public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
throws IOException {
// 根据 服务名称去查询可用实例
ServiceInstance serviceInstance = choose(serviceId);
return execute(serviceId, serviceInstance, request);
}
@Override
public ServiceInstance choose(String serviceId) {
// 获取负载均衡策略
ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory
.getInstance(serviceId);
// 执行负载均衡策略获取可以实例
Response<ServiceInstance> loadBalancerResponse = Mono.from(loadBalancer.choose())
.block();
return loadBalancerResponse.getServer();
}
}
loadBalancer 负载均衡策略实现:
目前只有一个RoundRobinLoadBalancer 轮询选择server的方式
public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceSupplier supplier = this.serviceInstanceSupplier.getIfAvailable();
return supplier.get().collectList().map(instances -> {
if (instances.isEmpty()) {
log.warn("No servers available for service: " + this.serviceId);
return new EmptyResponse();
}
// TODO: enforce order?
int pos = Math.abs(this.position.incrementAndGet());
ServiceInstance instance = instances.get(pos % instances.size());
return new DefaultResponse(instance);
});
}
}
4. 和ribbon 比较
默认负载均衡比较
ribbon 提供7种默认的负载均衡策略,常见的常见都有覆盖,一般我们都是使用 ZoneAvoidanceRule 复合判断server所在区域的性能和server的可用性选择server
配置方面丰富性
- 目前spring-cloud-loadbalancer
仅支持
重试操作的配置 - ribbon 支持超时、懒加载处理、重试及其和 hystrix整合高级属性等
5. 结论
老老实实用 ribbon
参考
Ribbon 真的能被 spring-cloud-loadbalancer 替代吗