Ribbon source tracking

1. What is Ribbon?

Ribbon is a load balancer released by Netflix, which helps control the behavior of HTTP and TCP clients. After configuring the service provider address for Ribbon, Ribbon can automatically help service consumers make requests based on a certain load balancing algorithm. Ribbon provides us with many load balancing algorithms by default, such as polling, random, etc. Of course, we can also implement custom load balancing algorithms for Ribbon.

In Spring Cloud, when Ribbon is used in conjunction with Nacos, Ribbon can automatically obtain a list of service provider addresses from Nacos Server, and request one of the service provider instances based on the load balancing algorithm. Shows the architecture when Ribbon is used in conjunction with Nacos.
Insert picture description here

2. Source code tracking

Why can we serviceaccess it only by entering the name? Before getting the ip and port. Obviously someone helped us get the ip and port of the service instance based on the service name. It is LoadBalancerInterceptor
our source code tracking:
Insert picture description here
continue to follow the execute method: found that the service of port 8001 has been obtained

org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient

Insert picture description here
If you follow the next time, you will find 8002

2. Load balancing strategy

Ribbon's default load balancing strategy is simple polling, we can test it:

Write the test class. In the source code just now, we see that the interception is used RibbonLoadBalanceClientfor load balancing. One of the choosemethods is introduced like this:
Insert picture description here
Now this is the method for load balancing to obtain instances. We inject objects of this class, and then test them:

package com.bruceliu.test;

import com.bruceliu.SpringcloudDemoConsumerApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author bruceliu
 * @create 2019-05-04 11:33
 * @description 负载均衡算法测试
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringcloudDemoConsumerApplication.class)
public class LoadBalanceTest {
    
    

    @Autowired
    RibbonLoadBalancerClient client;

    @Test
    public void test1(){
    
    
        for (int i = 0; i <10 ; i++) {
    
    
            ServiceInstance instance = this.client.choose("SPRINGCLOUD-DEMO-SERVICE");
            System.out.println(instance.getHost() + ":" + instance.getPort());
        }
    }
}

Operation result: It
Insert picture description here
conforms to our expected speculation, it is indeed a polling method .

Can we modify the load balancing strategy? Continue to trace the source code and find such a piece of code:
Insert picture description here
Let's see who this rule is:
Insert picture description here
The default value of the rule here is one RoundRobinRule, see the introduction of the class:
Insert picture description here
this is the meaning of polling.

We noticed that this class actually implements the interface IRule. Check it out:
Insert picture description here
Define a rule interface for load balancing.
It has the following implementations:
Insert picture description here
SpringBoot also provides us with a configuration entry to modify the load balancing rules:

SPRINGCLOUD-DEMO-SERVICE:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

The format is:, the {服务名称}.ribbon.NFLoadBalancerRuleClassNamevalue is the implementation class of IRule.
Tested again and found that the result became random:
Insert picture description here

2.1 Ribbon core component IRule (interview questions)

Insert picture description here

Strategy name The class name corresponding to the strategy Realization principle
Polling strategy (default) RoundRobinRule The polling strategy means to take down a provider in order each time, for example, there are 5 providers in total, the first is the first, the second is the second, the third is the third, and so on
Weighted polling strategy WeightedResponseTimeRule 1. Assign a weight according to the response time of each provider. The longer the response time and the smaller the weight, the lower the probability of being selected. 2. Principle: At the beginning, it is a polling strategy, and a timer is started. The average response time of each provider is collected every 30 seconds. When the information is sufficient, each provider is attached with a weight, and the provider is randomly selected according to the weight. A provider with a higher weight and a higher weight will be selected with a high probability.
Random strategy RandomRule Randomly select a provider from the list of providers
Minimum Concurrency Strategy BestAvailableRule Select the provider with the smallest number of concurrent requests being requested, unless the provider is in the fuse.
Retry mechanism based on "selected load balancing strategy" RetryRule 1. The "selected load balancing strategy" strategy is the round robin rule. 2. The retry strategy first sets a threshold time period. If the provider fails to be selected within this threshold time period, it will always try to use the "selection" strategy. Set load balancing strategy: polling strategy" and finally select an available provider
Usability Sensitive Strategy AvailabilityFilteringRule There are two kinds of providers with poor filtering performance: the first kind: filter out providers that have been failing to connect in eureka. The second kind: filter out providers with high concurrency.
Regional Sensitivity Strategy ZoneAvoidanceRule 1. Use a region as a unit to examine the availability, discard the unavailable region, and select the available provider from the remaining regions. 2. If one or more instances in this ip area are unreachable or slow in response, the ip area will be reduced. The weight of other ips in the selected.

2.2. Modify the algorithm for accessing the service

Method 1 : Modify the code to replace the load balancing strategy

Step 1: Create a new package that will not be scanned by the @ComponentScan component, such as: com.rules

Step 2: Create your own rule class of load balancing algorithm under this package

Step 3: Add a comment on the main startup class: @RibbonClient

package com.rules;

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

/**
 * @BelongsProject: MicroService
 * @BelongsPackage: com.rules
 * @CreateTime: 2020-11-18 16:50
 * @Description: TODO
 */
@Configuration
public class MyLoadBalanceRule {
    
    


    /**
     * @desc 自定义负载均衡规则,默认是轮询规则
     * @return
     */
    @Bean
    public IRule myRule(){
    
    
        //return new RandomRule(); // 改为随机算法规则
        return new RoundRobinRule(); // 轮询
    }

}




@EnableEurekaClient //开启客户端
@SpringBootApplication
@RibbonClient(name = "PRODUCT-SERVICE",configuration = MyLoadBalanceRule.class)
public class ProtalApp80 {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(ProtalApp80.class,args);
    }
}

Note: This class here cannot be configured under the same level directory and subdirectories of the SpringBoot startup class, why? Because the Ribbon configuration must be marked with @Configuration annotation, and cannot be scanned by @Component annotation or @SpringBootApplication (because it contains @Component). Because if it is scanned by @ComponetScan, it will cause all RibbonClients to share this configuration.

Method 2 : Modify the configuration file to replace the load balancing strategy.
The second method is to set the assigned strategy in application.properties

springcloud-alibaba-provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

'springcloud-alibaba-provider' is the name of the called service, and the following components are fixed.
At the same time comment out the content in method one

Guess you like

Origin blog.csdn.net/BruceLiu_code/article/details/114579991