Explanation on Ribbin's Custom Algorithms Creation in Spring Cloud

Keywords: Java Spring Nginx github

Explanation on Ribbin's Custom Algorithms Creation in Spring Cloud

Let me introduce Rabbin in Spring Cloud today.

Ribboin

Spring Cloud Ribbon is a client load balancing tool based on Netflix Ribbon.

Simply put, Ribbon is an open source project released by Netflix. Its main function is to provide client-side software load balancing algorithm, which connects Netflix mid-tier services together. Ribbon client components provide a complete set of configuration items such as connection timeouts, retries, etc. Simply put, by listing all the machines behind Load Balancer (LB) in the configuration file, Ribbon will automatically help you connect them based on certain rules (such as simple polling, random connections, etc.). We can also easily use Ribbon to implement custom load balancing algorithms.
The following picture:
1. What can Ribbon do: load balancing can be divided into two kinds. Centralized and in-process

Centralized LB
That is, to use a separate LB facility (hardware, such as F5, or software, such as nginx) between the consumer and provider of the service, which is responsible for forwarding access requests to the provider of the service through some strategy.

Intra process LB
Integrating LB logic into the consumer, the consumer learns from the service registry which addresses are available, and then chooses a suitable server from these addresses.
Ribbon belongs to in-process LB, which is only a class library integrated into the consumer process through which the consumer can get the address of the service provider.

2.Ribbon's Seven Algorithms

(1) Round Robin Rule: polling
(2) Random Rule: Random
(3) Availability Filtering Rule: It filters out services that are in circuit breaker tripping state due to multiple access failures.
There are also services with concurrent connections exceeding the threshold, and then access the remaining list of services according to polling policy
(4) Weighted Response Time Rule: Calculate the weight of all services according to the average response time, and the faster the response time, the higher the probability of service weight being selected.
If the statistics are insufficient at startup, the Round Robin Rule strategy is used, and the statistics are sufficient.
Switch to Weighted Response Time Rule
(5) RetryRule: Obtain services according to Round Robin Rule's policy first, and retry services within a specified time to obtain available services if they fail to obtain services
(6) Best Available Rule: It filters out the services that are in the circuit breaker tripping state due to multiple access failures, and then chooses a service with the smallest concurrency.
(7) Zone Avoidance Rule: Default rule to determine the performance of the server region and the availability of the server to select the server

3.Ribbon's self-defined algorithm,
Question: Still polling policy, but with new requirements, each server request is called five times. That is to say, once for every machine, now five times for every machine.
3.1. Add the properties of your own custom annotations to the startup class as shown below

Official documents clearly warn:

This custom configuration class cannot be placed under the current package and subpackage scanned by @ComponentScan, otherwise our custom configuration class will be shared by all Ribbon clients, that is to say, we can't achieve the goal of customization. As you can see from the following figure, the relationship between the custom configuration class and @ComponentScan is horizontal

3.2. Create your own custom configuration class (MySelfRule)

3.3. Create custom configuration classes (algorithmic rotation)
Rotation source download location: https://github.com/Netflix/ribbon/blob/master/ribbonloadbalancer/src/main/java/com/netflix/loadbalancer/RandomRule.java

Upon completion of the modification:

package com.atguigu.myrule;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

public class RandomRule_Roy extends AbstractLoadBalancerRule {

	// toltal = 0 // current total==5 and then proceed down
	// index = 0 // Currently available server address
	// Tot needs to be set to zero, but it's reached five times, our index=1
	// Analysis: 5 cycles, but only 3 micro-services
	// When it comes to 3, pull it over and reassign it
	private int total = 0;
	private int currentIndex = 0;
	

	public Server choose(ILoadBalancer lb, Object key) {
		if (lb == null) {
			return null;
		}
		Server server = null;

		while (server == null) {
			if (Thread.interrupted()) {
				return null;
			}
			List<Server> upList = lb.getReachableServers();
			List<Server> allList = lb.getAllServers();

			int serverCount = allList.size();
			if (serverCount == 0) {
				/*
				 * No servers. End regardless of pass, because subsequent passes
				 * only get more restrictive.
				 */
				return null;
			}
		////////////////////// Replace the following two lines of code with the following/////////////////////////////
		// 	int index = chooseRandomInt(serverCount);
		// 	server = upList.get(index);
		///////////////////////////////////////////////////
		///////////////////////////////////////////////////
			if (total < 5) {
				server = upList.get(currentIndex);
				total++;
			} else {
				total = 0;
				currentIndex++;
				if (currentIndex >= upList.size()) {
					currentIndex = 0;
				}
			}
		///////////////////////////////////////////////////
			if (server == null) {
				/*
				 * The only time this should happen is if the server list were
				 * somehow trimmed. This is a transient condition. Retry after
				 * yielding.
				 */
				Thread.yield();
				continue;
			}

			if (server.isAlive()) {
				return (server);
			}

			// Shouldn't actually happen.. but must be transient or a bug.
			server = null;
			Thread.yield();
		}

		return server;

	}

	protected int chooseRandomInt(int serverCount) {
		return ThreadLocalRandom.current().nextInt(serverCount);
	}

	@Override
	public Server choose(Object key) {
		return choose(getLoadBalancer(), key);
	}

	@Override
	public void initWithNiwsConfig(IClientConfig arg0) {
		// TODO Auto-generated method stub

	}
}

After completing the above operation, it can run directly.

OK!
In this way, we can realize the algorithm of custom rotation. Others are similar. It's easy to learn this and the rest.
Okay, you guys have a chance to see each other!

Posted by andyd34 on Mon, 06 May 2019 06:20:38 -0700