【spring cloud hoxton】Ribbon 真的能被 spring-cloud-loadbalancer 替代吗

背景

  • 早上刷圈看到 Spring Cloud Hoxton.M2 Released 的消息,随手发布到了我的知识星球,过了会有个朋友过来如下问题。 抽取半天时间学习spring-cloud-loadbalancer 的源码,整理出此文总结 

    https://oscimg.oschina.net/oscnet/f0f33c4d387352580bd6963b2f2479cf7dd.jpg

  • 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 的渊源
  1. 2017年spring 开始尝试开发新的项目 spring-cloud-loadbalancer 替代ribbon,项目托管在 spring-cloud-incubator 孵化器 (多提一嘴,spring cloud alibaba 等顶级的项目大多从此孵化出来的,代表着 spring cloud 的发展方向)
  2. 经过N个月的不维护,还以为spring 放弃此项目时,突然把此项目标记成归档迁移到spring-cloud-commons
  3. 发布2.2.0.M2 版本

如何使用

  • 这里基于 最新的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>

</dependencies></dependencymanagement>

  • 加入nacos-client ,使用 2.1.0版本,特别注意排除 ribbon依赖,不然loadbalancer 无效

<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坐标

<dependency>

       <groupid>org.springframework.cloud</groupid>

       <artifactid>spring-cloud-loadbalancer</artifactid>

</dependency>

  • 配置使用还是和 ribbon 一样配置

@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);

}

源码解析

LoadBalancerClient 实现

https://oscimg.oschina.net/oscnet/34a8546b004f8ee262c8cd3fbf1f4b7d7f9.jpg

  • 目前版本只提供了 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 负载均衡策略实现

https://oscimg.oschina.net/oscnet/8b21845f0b2ff217e9e094c26234186b6e9.jpg

  • 目前只有一个RoundRobinLoadBalancer 轮询选择server的方式

public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {

       public Mono<response<serviceinstance>&gt; choose(Request request) {

              ServiceInstanceSupplier supplier = this.serviceInstanceSupplier.getIfAvailable();

              return supplier.get().collectList().map(instances -&gt; {

                    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);

              });

       }

}

和ribbon 比较

默认负载均衡比较

  • ribbon 提供7中默认的负载均衡策略,常见的常见都有覆盖,一般我们都是使用 ZoneAvoidanceRule 复合判断server所在区域的性能和server的可用性选择server 

    https://oscimg.oschina.net/oscnet/d4584d428088b7d875833a16f1d22cde761.jpg

配置方面丰富性

  • 目前spring-cloud-loadbalancer 仅支持 重试操作的配置
  • ribbon 支持超时、懒加载处理、重试及其和 hystrix整合高级属性等

结论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值