Ribbon learning in spring cloud -- crazy God Theory

Tool: idea
Spring official website: https://spring.io/
Learn more about blog connections: https://blog.csdn.net/weixin_43591980/article/details/106255122
Video link: https://www.bilibili.com/video/BV1jJ411S7xr

What is Ribbon

  • SpringCloud Ribbon is a set of client-side load balancing tools based on Netflix Ribbon
  • In short, ribbon is an open source project released by Netflix. Its main function is to provide software load balancing algorithms for clients and connect Netflix's middle tier services together. The ribbon client component provides a series of complete configuration items, such as connection timeout, Retry, and so on. To put it simply, list all the machines behind the LoadBalancer (LB: load balancer for short) in the configuration file. Ribbon will automatically help you connect these machines based on certain rules (such as simple polling, random connection, etc.). We can also easily use ribbon to implement custom load balancing algorithms
    Load balancing?

Ribbon role (what can you do)

  • LB, Load Balance, is an application often used in microservices or distributed clusters.
  • Load balancing simply means that users' requests are evenly distributed to multiple services, so as to achieve the HA (high availability) core role of the system
  • Common load balancing software include Nginx, Lvs (Linux virtual machine server), etc. Apache+Tomcat also modifies the configuration to achieve load balancing
  • Both Dubbo and spring cloud provide us with load balancing. The load balancing algorithm of spring cloud can be customized
  • Simple classification of load balancing:
    • Centralized LB
      • That is, an independent LB facility is used between the service consumer and the service provider to enter nginx (reverse proxy server). This facility is responsible for forwarding access requests to the service provider through a certain policy! Learn more nginx: https://blog.csdn.net/weixin_43122090/article/details/105461971
    • Advance program LB
      • The LB logic is integrated into the consumer (i.e. the client). The consumer knows which addresses are available from the service registry, and then selects an appropriate server from these addresses.
      • Ribbon belongs to in-process LB. it is just a class library integrated into the consumer process. The consumer obtains the address of the service provider through it!

Because the integration ribbon is in the form of a client, it is written on the client, that is, the integration on springcloud-consumer-dept-80 Find it from maven warehouse and choose 1.4 Version 6.

Import ribbon dependency in pom file

<!--ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--eureka-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

Write configuration, application YML file

server:
  port: 80

#eureka configuration
eureka:
  client:
    register-with-eureka: false # Do not register yourself with eureka
    service-url:
      defaultZone: http://eureka7001:com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003:com:7003/eureka/

DeptConsumer_80, turn on Eureka function

ConfigBean

DeptConsumerController

That is, access through the service name shown in the figure below

Access application Which three addresses in YML

Run any two of 7001, 7002 and 7003 to prevent the memory from loading fast enough. Then run the main startup class of springcloud-consumer-dept-80 and enter the access address: http://localhost/consumer/dept/list

If you want to know what load balancing the ribbon does every time you refresh, you have to add service providers
As service providers increase, so do databases

Open the Navicat navigation cat, find the database, and then export it

Open new query

Modify statement

Then, first run the new database, then run the new table, and finally insert data in the data table
Run new database

Run new table

Run insert data in data table

Refresh, and then see this to prove that a database has been successfully created

Then repeat the above operation to create a database and remember that the name of the database has to be changed.
Add all the newly created databases in idea

Then make two copies of springcloud-provider-dept-8001 and change the name

Copy what should be in springcloud-provider-dept-8001 to springcloud-provider-dept-8002 and springcloud-provider-dept-8003, and change all the names that should be changed. Special attention should be paid to application The port number in the YML file, the connected database, and the description information in eureka. Then change the name of the main startup class.
Start the 7001 cluster, and then start consumers 8001, 8002 and 8003. Then do not shut down the started service

Start spring cloud-consumer-dept-80 again and enter the address http://localhost/consumer/dept/list Visit db01 for the first time

The second time it's different, polling to change

Ribbon algorithm
The above is the method of polling access provider, and the following is random access
In spring cloud-consumer-dept-80, call the encapsulation method written by others in ConfigBean

But it shouldn't be here under normal circumstances. Deptconsumer should be started in the main class_ 80, so:
Create a package under springcloud-consumer-dept-80, and then create a class.

It's the official website. It's recommended not to put it on the same level. If you want to know more, you can go to the official website of spring cloud.

Under springcloud-consumer-dept-80, the main startup class is deptconsumer_ Write configuration on 80

Then cut the myRule method in the ConfigBean into the routing component spring cloudrule written by yourself

Into this, copy all the contents, and then transform them

Copy it to the package of myrule and rename it ChangAnRandomRule

After copying, change the name and delete the original copy.

ChangAnRandomRule

package com.myrule;
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;
import java.util.concurrent.ThreadLocalRandom;
public class ChangAnRandomRule extends AbstractLoadBalancerRule {
    //The red warning is a suppression warning, which can be ignored
    //@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
    //Each service is accessed 5 times and the next service is replaced (3)
    //total=0, default = 0, if = 5, we point to the next service node
    //index=5, the default is 0. If total=5, index+1
    private int total = 0;//Number of calls
    private int currentIndex=0;//Who is currently providing services
    public Server choose(ILoadBalancer lb, Object key) {
        //Default random algorithm
        if (lb == null) {
            return null;
        }
        Server server = null;
        //Check to see if it was interrupted
        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            //Access to living services
            List<Server> upList = lb.getReachableServers();
            //Get the service you want
            List<Server> allList = lb.getAllServers();
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }
//            //Generating interval random number
//            int index = chooseRandomInt(serverCount);
//            //Randomly get one from a living service
//            server = upList.get(index);
            //Custom code---------------
            if(total<5){
                server = upList.get(currentIndex);
                total++;
            }else{
                total=0;
                currentIndex++;
                if (currentIndex>upList.size()){
                    currentIndex=0;
                }
                //Get the specified service from the living service to operate
                server = upList.get(currentIndex);
            }
            //----------------
            if (server == null) {
                Thread.yield();
                continue;
            }
            if (server.isAlive()) {
                return (server);
            }
            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 clientConfig) {
      // TODO Auto-generated method stub
      
   }
}

Back to spring cloud rule

package com.myrule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringCloudRule {
    //Call the method written by yourself. The default is polling
    @Bean
    public IRule myRule(){
        return new ChangAnRandomRule();
    }
}

Visit the browser, change a server every 5 times, and use the polling method. However, if the access speed is fast, the service will be interrupted. At this time, RetryRule can be used to solve it.

Keywords: Java Spring Cloud

Added by ViperSBT on Tue, 21 Dec 2021 09:01:17 +0200