Detailed introduction of Ribbon load balancer (7)

Simple polling rules for LoadBalancer

In the previous blog, we used Ribbon to implement the load and polled the request for the service. Let's analyze the LoadBalancer (load balancer) that implements load balancing in Ribbon to see how it does it at the bottom, and How these request rules are configured.

First get the ribbon-client project in our previous blog, create a new LoadBalancerTest class under the com.init.springCloud package, create a new basic Ribbon load balancer in this class, then create a service list, and put the service list Load it into the basic load balancer, and then let the load balancer execute the selection service multiple times. We can view its selection rules by outputting the service information:

package com.init.springCloud;

import java.util.ArrayList;
import java.util.List;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

public class LoadBalancerTest {

	public static void main(String[] args) {
		ILoadBalancer loadBalancer = new BaseLoadBalancer();
		List<Server> servers = new ArrayList<Server>();
		servers.add(new Server("localhost",8082));
		servers.add(new Server("localhost",8083));
		loadBalancer.addServers(servers);
		for(int i=0; i<10; i++){
			// The parameter is an object that the load balancer can use to determine which server to return. Leave blank to not use
			Server chosedServer = loadBalancer.chooseServer(null);
			System.out.println("The selected service is: "+chosedServer);
			
		}
	}
	
}

Run the main() method of LoadBalancerTest, and you can see that the console polling has selected two services.


By tracking LoadBalancer's chooseServer method, we can see that the load balancer uses RoundRobinRule by default



Rules for custom load balancers

Referring to the above RoundRobinRule, we also implement the IRule interface to create our own rules, create a new MyRule class under the com.init.springCloud package, implement the IRule interface, and write a rule class with a 20% probability of port 8082 service:

package com.init.springCloud;

import java.util.List;
import java.util.Random;

import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;

public class MyRule implements IRule {

	private ILoadBalancer lb;
	
	@Override
	public Server choose(Object key) {
		Random random = new Random();
		Integer num = random.nextInt(10);//Get the value in the 10 random numbers 0-9
		//Get all services in the transport load balancer
		List<Server> servers = lb.getAllServers();
		if(num>7){//Return 8082 port service
			return chooseServerByPort(servers,8082);
		}
		//return 8083 port service
		return chooseServerByPort(servers,8083);
	}
	
	private Server chooseServerByPort(List<Server> servers,Integer port){
		for (Server server : servers) {
			if(server.getPort() == port){
				return server;
			}
		}
		return null;
	}

	@Override
	public void setLoadBalancer(ILoadBalancer lb) {
		this.lb = lb;
	}

	@Override
	public ILoadBalancer getLoadBalancer() {
		return lb;
	}

}

Then create a class MyRuleTest, let the load balancer load our new rule class, and implement our own load, content and LoadBalancerTest class roughly:

package com.init.springCloud;

import java.util.ArrayList;
import java.util.List;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;

public class MyRuleTest {

	public static void main(String[] args) {
		
		BaseLoadBalancer loadBalancer = new BaseLoadBalancer();
		
		MyRule myRule = new MyRule();
		loadBalancer.setRule(myRule);
		
		List<Server> servers = new ArrayList<Server>();
		servers.add(new Server("localhost",8082));
		servers.add(new Server("localhost",8083));
		
		loadBalancer.addServers(servers);
		
		for(int i=0; i<10; i++){
			// The parameter is an object that the load balancer can use to determine which server to return. Leave blank to not use
			Server chosedServer = loadBalancer.chooseServer(null);
			System.out.println("The selected service is: "+chosedServer);
			
		}
		
	}
	
}

Run the main() method of MyRuleTest, you can see that the probability that the load balancer selects port 8082 becomes smaller


Ribbon's components can be set programmatically, or they can be part of client-side configuration properties and created through reflection. These related properties need to be implemented in the configuration file in the form of "client name"."namespace"."property name". Ribbon provides settings for the following properties:

  1. NFLoadBalancerClassName Load balancer class name setting
  2. NFLoadBalancerRuleClassName rule class name setting
  3. NFLoadBalancerPingClassName Ping class name setting
  4. NIWSServerListClassName service list class name setting
  5. NIWSServerListFilterClassName Service list filter name setting

In order to verify whether the created custom rules can take effect, we use the above configuration method to modify the RibbonTest class of the ribbon-client project, and add a line of code to configure the custom load balancer rules. The latest code of the RibbonTest class:

package com.init.springCloud;

import com.netflix.client.ClientException;
import com.netflix.client.ClientFactory;
import com.netflix.client.http.HttpRequest;
import com.netflix.client.http.HttpResponse;
import com.netflix.config.ConfigurationManager;
import com.netflix.niws.client.http.RestClient;

public class RibbonTest {

	public static void main(String[] args) {
		
		//Set the server to request
		ConfigurationManager.getConfigInstance().setProperty(
	      		"sample-client.ribbon.listOfServers",
	      		"localhost:8082,localhost:8083");
		//Configure custom load balancer rules
		ConfigurationManager.getConfigInstance().setProperty(
	      		"sample-client.ribbon.NFLoadBalancerRuleClassName",
	      		MyRule.class.getName());
		//Set up the REST request client
		RestClient client = (RestClient) ClientFactory.getNamedClient("sample-client");
		//create request instance
		HttpRequest request = HttpRequest.newBuilder().uri("/search/1").build();
		//Send 10 consecutive requests to the server
		for(int i=0; i<10; i++){
			try {
				HttpResponse response = client.executeWithLoadBalancer(request);
				String result = response.getEntity(String.class);
				System.out.println("Request result: "+result);
			} catch (ClientException e) {
				e.printStackTrace ();
			} catch (Exception e) {
				e.printStackTrace ();
			}
		}
		
	}
	
}

Then start the ribbon-server, type two ports 8082 and 8083 in the console, run two different service instances, and then come back to run the main() method of RibbonTest of the ribbon-client project, you can see the results of the console output, which proves that we The configured rule class succeeded.


Ribbon built-in rules

  1. AvailabilityFilteringRule: This rule will skip servers that are considered "circuit tripped" or have a high number of concurrent connections.
  2. BestAvailableRule: This rule skips the "circuit-tripped" server and picks the one with the lowest number of concurrent requests.
  3. PredicateBasedRule: A rule that delegates server filtering logic to an instance of {@link AbstractServerPredicate}. After filtering, the server returns from the filtered list in a round-robin fashion.
  4. RandomRule: A load balancing strategy for randomly distributing traffic.
  5. RetryRule: When the server selection is unsuccessful within a configuration period, it always tries to select an available server by using the subRule method.
  6. RoundRobinRule: This rule simply polls to select servers. It is often used as a default rule or fallback for more advanced rules.
  7. WeightedResponseTimeRule: For this rule, each server is given a weight based on its average response time. The longer the response time, the smaller the resulting weight. The rules randomly select a server, where the likelihood is determined by the server's weight.
  8. ZoneAvoidanceRule: Use ZoneAvoidancePredicate and AvailabilityPredicate to determine whether to select a server. The previous one determines whether the running performance of a zone is available, and removes the unavailable zone (all servers). AvailabilityPredicate is used to filter out servers with too many connections.

Some commonly used rules are highlighted in blue fonts. In fact, most of the rules use RoundRobinRule at the bottom.

Source code click here

Spring Cloud series:

Spring Cloud introduction and environment construction (1)

Simple use of Spring Boot (2)

Simple example of Spring Cloud service management framework Eureka (3)

Spring Cloud service management framework Eureka project cluster (4)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325592751&siteId=291194637