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
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
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);
}