ribbon, restTemplate load balancing service call

ribbon concept

Spring cloud ribbon is a set of client load balancing tools 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 algorithms and services.
Complete configuration items such as connection timeout, retry, etc. Simply put, Load Balancer (LB for short) is listed in the configuration file to help you connect to these machines based on certain rules (such as simple polling, random connection, etc.).

Currently entering maintenance mode, alternative: spring cloud loadBalance.


restTemplate api

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

getObject, getEntity
postObject, postEntity

Load balancing

What is LB Load Balance?
Simply put, the user's requests are equally distributed to multiple services, so as to achieve the system's HA (high availability).
Common load balancing includes software Nginx, LVS, hardware F5, etc.
Ribbon Local Load Balancing Client VS Nginx Server Load Balancing The difference between
Nginx is server load balancing, all client requests will be handed over to nginx, and then nginx will forward the request. That is, load balancing is implemented by the server.
Ribbon local load balancing. When calling the microservice interface, it will obtain the registration information service list in the registry and cache it locally in the JVM, thereby implementing RPC remote service invocation technology locally.

Load balancing + RestTemplate call.

ribbon core component IRule

ribbon client load balancing interface and implementation class
interface and subclasses

Insert picture description here
Algorithm implementation


Replace the default polling algorithm, use random

package top.bitqian.rule; // 不要同mainBoot一个目录

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

/**
 * 自定义ribbon 负载均衡规则代替默认轮询规则
 * @author echo lovely
 * @date 2020/12/6 17:34
 */

@Configuration
public class SelfRule {
    
    

    @Bean
    public IRule getIRule() {
    
    

        // 随机
        return new RandomRule();
    }

}

Then add @RibbonClient annotation to the main startup class .

Imitate the source code to rewrite polling

负载均衡算法原理: rest接口的第几次请求数%服务器集群总数量 = 实际服务调用服务器的下标。
每次重启服务后,rest接口从1开始。

interface

package top.bitqian.springcloud.lb;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

/**
 * 负载均衡 接口--> 轮询~
 */
public interface LoadBalance {
    
    

    /**
     * 根据可用的服务实例列表 轮询获取某个实例~
     * @param serviceInstanceList 可用服务实例列表
     * @return 轮询后的某个服务实例~
     */
    ServiceInstance getInstance(List<ServiceInstance> serviceInstanceList);

}


achieve

package top.bitqian.springcloud.lb.impl;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import top.bitqian.springcloud.lb.LoadBalance;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 仿照源码写轮询算法
 * @author echo lovely
 * @date 2020/12/8 20:37
 */

@Component
public class MyLoadBalance implements LoadBalance {
    
    

    // init 0
    private final AtomicInteger atomicInteger = new AtomicInteger(0);

    public final int getAndIncrease() {
    
    
        int current;
        int next;

        do {
    
    
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current + 1;

        } while (!this.atomicInteger.compareAndSet(current, next)); // 期望值,修改值

        System.out.println("the next value -----> " + next);

        return next;
    }

    @Override
    public ServiceInstance getInstance(List<ServiceInstance> serviceInstanceList) {
    
     // 机器列表

        // 得到服务器的下标位置
        int index = getAndIncrease() % serviceInstanceList.size();

        return serviceInstanceList.get(index);
    }
}


controller
	// 测试手写的轮询算法~
    @GetMapping("/consumer/payment/lb")
    public String getPaymentByLb() {
    
    

        // 根据服务名获取服务列表
        List<ServiceInstance> serviceInstanceList =
                discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");

        // 1 2, 1 2, 1 2, 获取服务~
        ServiceInstance instance = myLb.getInstance(serviceInstanceList);

        URI uri = instance.getUri();

        return restTemplate.getForObject(uri + "/payment/lb", String.class);
    }

Guess you like

Origin blog.csdn.net/qq_44783283/article/details/111079799