当前位置:网站首页>8. Ribbon load balancing service call

8. Ribbon load balancing service call

2022-06-26 13:44:00 Bitter candy

Study B Standing still, Mr. Zhou Yang of Silicon Valley SpringCloud The lecture notes

1.Ribbon summary

1.1 What is it? ?

 Insert picture description here Official website :https://github.com/Netflix/ribbon/wiki/Getting-Started
Ribbon At present, it also enters maintenance mode

1.2 What can I do? ?

LB( Load balancing )
 Insert picture description here Centralized LB
 Insert picture description here In process LB
 Insert picture description here Load balancing +RestTemplate call

1.3 Architecture description

 Insert picture description here  Insert picture description here summary :Ribbon In fact, it is a soft load balancing client component , It can be used in combination with other clients that require requests , and eureka Combination is just one example .

1.4Eureka jar Package contains Ribbon

 Insert picture description here  Insert picture description here

1.5 The second said RestTemplate Use

Official website :https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html

ForObject Method /ForEntity Method
 Insert picture description here

2.Ribbon Core components IRule

2.1 IRule: Select a service to be accessed from the service list according to a specific algorithm

 Insert picture description here  Insert picture description here

2.2 How to replace

2.1 modify cloud-consumer-order80

 Insert picture description here  Insert picture description here

2.2 newly build package : com.atguigu.myrule, The upper package and the lower package MySelfRule Rule class

@Configuration
public class MySelfRule {
    

    @Bean
    public IRule myRule(){
    
        return new RandomRule();// Defined as random 
    }
}

2.3 The main startup class adds @RibbonClient

@EnableEurekaClient
@SpringBootApplication
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderMain80 {
    
    public static void main(String[] args) {
    
        SpringApplication.run(OrderMain80.class,args);
    }
}

2.4 test :

http://localhost/consumer/payment/get/3
Find out port The return is random , No longer polling .

3.Ribbon Load balancing algorithm

3.1 RoundRobinRule The source code parsing

The core algorithm :next = (current + 1) % lb.getAllServers().size();
Returns the subscript =( The subscript +1) Take the remainder of the number of nodes , The final returned subscript is always less than or equal to the number of nodes -1;

public Server choose(ILoadBalancer lb, Object key) {
    
        if (lb == null) {
    
            log.warn("no load balancer");
            return null;
        } else {
    
            Server server = null;
            int count = 0;

            while(true) {
    
                if (server == null && count++ < 10) {
    
                    List<Server> reachableServers = lb.getReachableServers();
                    List<Server> allServers = lb.getAllServers();
                    int upCount = reachableServers.size();
                    int serverCount = allServers.size();
                    if (upCount != 0 && serverCount != 0) {
    
                        int nextServerIndex = this.incrementAndGetModulo(serverCount);
                        server = (Server)allServers.get(nextServerIndex);
                        if (server == null) {
    
                            Thread.yield();
                        } else {
    
                            if (server.isAlive() && server.isReadyToServe()) {
    
                                return server;
                            }

                            server = null;
                        }
                        continue;
                    }

                    log.warn("No up servers available from load balancer: " + lb);
                    return null;
                }

                if (count >= 10) {
    
                    log.warn("No available alive servers after 10 tries from load balancer: " + lb);
                }

                return server;
            }
        }
    }
// do while  The loop executes the body of the loop at least once , When the return result is true, Then continue to execute the loop body , return false, Exit the circulatory body 
// AtomicInteger Of compareAndSet(int expect, int update); Used CAS Algorithm , Only when expect The expected value will be updated 
    private int incrementAndGetModulo(int modulo) {
    
        int current;
        int next;
        do {
    
            current = this.nextServerCyclicCounter.get();
            next = (current + 1) % modulo;
        } while(!this.nextServerCyclicCounter.compareAndSet(current, next));
				//  return false, Exit the circulatory body 
        return next;
    }

3.2 Handwritten polling load balancing

3.2.1 8001/8002 Micro service transformation
@GetMapping(value = "/payment/lb")
public String getPaymentLB(){
    
    return serverPort;
}
3.2.2 80 Order micro service transformation

ApplicationContextBean Get rid of @LoadBalanced

newly build LoadBalancer Interface

public interface LoadBalancer {
    
     //  How many machines are there in the collection server that can provide services , And on the list Inside 
    ServiceInstance instances(List<ServiceInstance> serviceInstances);

newly build LoadBalancerImpl Implementation class , mark @Component annotation , The location is under the startup class subpackage

@Component
public class LoadBalancerImpl implements LoadBalancer {
    

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    private final int getAndIncrement(int size){
    
        for (;;){
    
            int current = this.atomicInteger.get();
            int next = (current+1)%size;
            //  If current The value of has not changed , Just go back to next
            if(this.atomicInteger.compareAndSet(current,next)){
    
            //  return true, Exit the circulatory body 
                return next;
            }
        }
    }

    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
    
        //  Get the subscript location of the server 
        int index = getAndIncrement(serviceInstances.size());
        return serviceInstances.get(index);
    }
}

modify OrderController


    @Resource
    private LoadBalancer loadBalancer;

    @Resource
    private DiscoveryClient discoveryClient;
    
@GetMapping(value = "/consumer/payment/lb")
     public String getPaymentLB(){
    
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        if (instances == null || instances.size() <= 0){
    
            return null;
        }
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        URI uri = serviceInstance.getUri();
        return restTemplate.getForObject(uri+"/payment/lb",String.class);
    }

test :http://localhost/consumer/payment/lb
Stop 8001 service , Tests found discoveryClient.getInstances The online service node is returned . If it's turned off eureka Self protection of , So back port It has always been 8002

原网站

版权声明
本文为[Bitter candy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206261253449727.html