[spring cloud hoxton] can Ribbon really be replaced by spring cloud loadbalancer (load balancing)

1. Background

Spring Cloud Ribbon is a client load balancing tool based on HTTP and TCP, which is implemented based on Netflix Ribbon. Through the encapsulation of Spring Cloud, we can easily automatically convert service-oriented REST template requests into client-side load balanced service calls. Although Spring Cloud Ribbon is just a tool class framework, it does not need to be deployed independently like service registry, configuration center and API gateway, but it exists in almost every micro service and infrastructure built by Spring Cloud. Because the calls between micro services and the request forwarding of API gateway are actually implemented through the Ribbon, including Feign, which we will introduce later. It is also a tool based on the Ribbon. Therefore, the understanding and use of Spring Cloud Ribbon is very important for us to use Spring Cloud to build microservices.

ribbon has been built into many micro service frameworks.

Spring Cloud Hoxton.M2 is the first to integrate the new loadbalancer implementation to replace the Ribbon version.

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.

Origin of spring cloud loadbalancer

  • In 2017, spring began to try to develop a new project spring cloud loadbalancer instead of ribbon. The project is hosted in
    Spring cloud incubator
    (to mention more, most top projects such as spring cloud and Alibaba have been hatched since then, representing the development direction of spring cloud)
  • After N months of non maintenance, when I thought spring would give up this project, I suddenly marked it as an archive and migrated it to spring cloud Commons
  • Release 2.2 Version 0.m2

2. How to use spring cloud loadbalancer

This is based on the latest Hoxton M2 version can only be used, so configure the spring agent maven Library:

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

Join the Nacos client and use 2.1 In version 0, pay special attention to excluding ribbon dependencies, otherwise the loadbalancer is invalid.

Take spring cloud starter Alibaba Nacos discovery as an example. ribbon dependency has been built in, so it needs to be excluded:

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

Add the loadbalancer pom coordinates and inherit the spring cloud version number:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

The configuration is the same as that of the ribbon, @ LoadBalanced flag:

@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. Source code analysis

The core class is BlockingLoadBalancerClient


The current version only provides the implementation of BlockingLoadBalancerClient. Please pay attention to the Chinese notes

// Note that the deletion retains only the core code
public class BlockingLoadBalancerClient implements LoadBalancerClient {

	@Override
	public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
			throws IOException {
		// Query available instances by service name
		ServiceInstance serviceInstance = choose(serviceId);
		return execute(serviceId, serviceInstance, request);
	}

	@Override
	public ServiceInstance choose(String serviceId) {
	    // Get load balancing policy
		ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory
				.getInstance(serviceId);
		// Execute load balancing policy to obtain instances
		Response<ServiceInstance> loadBalancerResponse = Mono.from(loadBalancer.choose())
				.block();
		return loadBalancerResponse.getServer();
	}

}

Implementation of loadBalancer load balancing strategy:

At present, there is only one roundrobin loadbalancer polling method to select the 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. Comparison with ribbon

Default load balancing comparison

The ribbon provides the default load balancing policy in 7. Common policies are covered. Generally, we use the ZoneAvoidanceRule to judge the performance of the server area and the availability of the server, and select the server

Configuration richness

  • Currently, spring cloud loadbalancer only supports the configuration of retry operation
  • ribbon supports timeout, lazy load processing, retry and its integration with hystrix advanced properties

5. Conclusion

Honest and practical ribbon

reference resources

Can Ribbon really be replaced by spring cloud loadbalancer

Keywords: Load Balance Spring Cloud ribbon

Added by madhu on Fri, 17 Dec 2021 02:43:52 +0200