SpringBoot极简教程 · Spring Boot Spring-BootSpring Boot 核心技术

【spring cloud hoxton】Ribbon 真的能被

2019-08-21  本文已影响6人  冷冷zz

背景

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.
  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 版本

如何使用

<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>
<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>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
@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 实现

// 删除只保留了核心代码注意
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 负载均衡策略实现

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

}

和ribbon 比较

默认负载均衡比较

配置方面丰富性

结论

上一篇 下一篇

猜你喜欢

热点阅读