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
替代ribbon,项目托管在 spring-cloud-incubator 孵化器
(多提一嘴,spring cloud alibaba 等顶级的项目大多从此孵化出来的,代表着 spring cloud 的发展方向)
<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); }
// 删除只保留了核心代码注意 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(); } }
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); }); } }
ZoneAvoidanceRule
复合判断server所在区域的性能和server的可用性选择server
spring-cloud-loadbalancer