Spring cloud Alibaba: load balancer Ribbon

Posted by metuin on Wed, 22 Dec 2021 01:28:22 +0100

What is ribbon

At present, the mainstream load schemes are divided into the following two types:

  • Centralized load balancing uses independent agents between consumers and service providers, including hardware (e.g. F5) and software (e.g. nginx)
  • The client does load balancing according to its own request, and the Ribbon belongs to the client to do load balancing

SpringCloud Ribbon is a set of client-side load balancing tools based on Netflix Ribbon. The Ribbon client component provides a series of perfect configurations, such as timeout, Retry, etc. Get all machine instances provided by the service through the Load Balancer, and the Ribbon will automatically call these services based on certain rules (polling, random, etc.), and the Ribbon can also implement our own load balancing algorithm.

1.1 load balancing of client

For example, in the Ribbon in spring cloud, the client will have a server address list. Before sending a request, select a server through the load balancing algorithm, and then access it. This is client load balancing, that is, load balancing algorithm allocation is performed on the client.

 

1.2 load balancing at the server

For example, nginx performs load balancing through nginx, first sends a request, then selects one of multiple servers for access through the load balancing algorithm; That is, the load balancing algorithm is allocated at the server.

1.3 common load balancing algorithms

  • Random. It is generally used less by randomly selecting services for execution
  • Polling. The default implementation method of load balancing is to queue up for processing after the request comes
  • Weighted polling. Through the classification of server performance, the servers with high configuration and low load are assigned higher weights to balance the pressure of each server
  • Address hash. Server scheduling is carried out through modular mapping of hash value of client request address. ip hash
  • The minimum number of connections. Even if the request is balanced, the pressure may not be balanced. The minimum number of connections method is to allocate the request to the server with the lowest current pressure according to the server's conditions, such as request backlog and other parameters. Minimum active number

Nacos uses Ribbon

1. Nacos discovery relies on the ribbon, so you can no longer refer to the ribbon dependency

 2. Add @ LoadBalanced annotation

  

 3. Modify Controller

Ribbon load balancing strategy

IRule 

This is the parent interface of all load balancing policies. The core method inside is the choose method, which is used to select a service instance.

AbstractLoadBalancerRule

AbstractLoadBalancerRule is an abstract class. It mainly defines an ILoadBalancer, which is the load balancer mentioned above. The purpose of defining it here is to assist the load balancing strategy to select appropriate server instances.

  • Random rule: this load balancing strategy is to randomly select a service instance
  • Round robin rule: this load balancing strategy is a linear polling load balancing strategy
  • RetryRule: retry based on polling
  • WeightResponseTimeRule: weight. The shorter the average response time of a service, the greater the weight, and the greater the probability that the service instance is selected to perform tasks.
  • Clientconfignenabledroundrobin rule: consistent with the selection policy of roundrobin rule.
  • Best available rule: filter out the failed service instances, and then find the service instance with the smallest concurrent request to use
  • ZoneAvoidanceRule: default rule
  • AvailabilityFilteringRule:

Modify the default load balancing policy

There are two ways to modify the default load balancing policy

1. Implementation based on configuration class

1.1 add configuration class

package com.zjb.ribbon;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Ribbon Load balancing policy configuration class
 */
@Configuration
public class RibbonRandomRuleConfig {

    /**
     * 
     * @return
     */
    @Bean
    public IRule iRule(){
        return new RandomRule();
    }
}

Note that there are pits here. It cannot be written in the @ CompentScan scan of the @ SpringBootApplication annotation, otherwise the custom configuration class will be shared by all RibbonClients. This is not recommended. yml is recommended.      

1.2 modify the startup class, add the @ RibbonClients annotation, and use @ RibbonClient to specify the service name and its load balancing policy

package com.zjb.order;

import com.zjb.ribbon.RibbonRandomRuleConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;

@SpringBootApplication
//Configuring multiple RibbonRandomRuleConfig cannot be scanned by @ CompentScan of @ SpringBootApplication, otherwise it is the global configuration effect
@RibbonClients({
            @RibbonClient(name = "stock-service",configuration = RibbonRandomRuleConfig.class)
})
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}

2. Implementation based on configuration file

2.1 modify application YML file

# Called service name
stock-service:
  ribbon:
    # Specifies to use a load balancing policy
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Custom load balancing policy

Here we implement a simple random load balancing strategy, focusing on how to customize the load balancing strategy

Add diyribonrule and inherit AbstractLoadBalancerRule class

package com.zjb.ribbon;

import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.ThreadLocalRandom;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;

import java.util.List;

public class DIYRibbonRule extends AbstractLoadBalancerRule {
    
    public Server choose(Object o) {
        ILoadBalancer loadBalancer = this.getLoadBalancer();

        //Or get the currently requested service instance
        List<Server> reachableServers = loadBalancer.getReachableServers();

        int i = ThreadLocalRandom.current().nextInt(reachableServers.size());

        Server server = reachableServers.get(i);
        return server;
    }

    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}

When calling, we find that the first call will be very slow. This is because of lazy loading. We load only when calling. How should we solve this problem?

Enable hungry loading to solve the problem of slow calling for the first time

ribbon:
  eager-load:
    #Turn on Ribbon starvation loading
    enabled: true
    #Configure stock service to load using ribbon, and multiple are separated by commas
    clients: stock-service

 

Topics: Load Balance Framework ribbon