当前位置:网站首页>Three ways of extending ribbon to support Nacos weight
Three ways of extending ribbon to support Nacos weight
2022-06-22 20:56:00 【A rookie is a great God】
Nacos Support weight configuration , This is a practical function , for example :
- Set the weight of the machine with poor performance low , The weight of the machine with good performance is set high , Give priority to requests to high-performance machines ;
- When an exception occurs in an instance , Set the weight low , Troubleshoot problems , After troubleshooting, restore the weight ;
- When you want to offline an instance , You can set the weight of this instance to 0, In this way, the traffic will not reach the instance —— Then shut down the instance , In this way, you can achieve elegant offline . Of course this is for Nacos Customized elegant offline solution ——Spring Cloud in , There are many postures to achieve elegant offline , See :《 Practical skills :Spring Cloud in , How to gracefully get off line microservice ?》 , In it, the author summarizes four elegant offline methods .
However, the test found that ,Nacos Weight configuration pair Spring Cloud Alibaba Invalid . in other words , No matter in Nacos How to configure on the console , When calling, the weight setting is ignored .
Spring Cloud Alibaba Through integration Ribbon The way , Load balancing is realized . The load balancing rules used are ZoneAvoidanceRule .
This section discusses how to extend Ribbon, Let it support Nacos Weight configuration , The author summarizes three schemes .
programme 1: Implement load balancing rules by yourself
Ideas :
First of all Ribbon Load balancing rules are OK .
- Weight configuration , Can be obtained from the instance information .
- Configure based on weight , Calculate an example .
Code :
@Slf4j
public class NacosWeightRandomV1Rule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object key) {
List<Server> servers = this.getLoadBalancer().getReachableServers();
List<InstanceWithWeight> instanceWithWeights = servers.stream()
.map(server -> {
// The registry uses only Nacos, Not using other registries at the same time ( for example Eureka), Theoretically, it will not be realized
if (!(server instanceof NacosServer)) {
log.error(" invalid parameter ,server = {}", server);
throw new IllegalArgumentException(" invalid parameter , No NacosServer example !");
}
NacosServer nacosServer = (NacosServer) server;
Instance instance = nacosServer.getInstance();
double weight = instance.getWeight();
return new InstanceWithWeight(
server,
Double.valueOf(weight).intValue()
);
})
.collect(Collectors.toList());
Server server = this.weightRandom(instanceWithWeights);
log.info(" Selected server = {}", server);
return server;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private class InstanceWithWeight {
private Server server;
private Integer weight;
}
/**
* Random according to weight
* Algorithm reference https://blog.csdn.net/u011627980/article/details/79401026
*
* @param list The instance list
* @return Random results
*/
private Server weightRandom(List<InstanceWithWeight> list) {
List<Server> instances = Lists.newArrayList();
for (InstanceWithWeight instanceWithWeight : list) {
int weight = instanceWithWeight.getWeight();
for (int i = 0; i <= weight; i++) {
instances.add(instanceWithWeight.getServer());
}
}
int i = new Random().nextInt(instances.size());
return instances.get(i);
}
}
WARNING
There is room for optimization in this code , Just to demonstrate the process of thinking , Not recommended for production , If you intend to use this scheme to realize , Please refer to the following two optimizations :
- Simplicity , I'll go straight to double Weight of type (weight), Into the integer To calculate the , There is a loss of precision .
- InstanceWithWeight Is too heavy , stay
weightRandomTwo more floors for loop , It's quite memory intensive , Suggest Baidu other weight random algorithm optimization . However, there are generally only three or five instances of a microservice in an actual project , So the memory consumption can be tolerated . No optimization is a big problem .
programme 2: utilize Nacos Client The ability of [ recommend ]
Ideas :
Reading code Nacos In the process of source code , Find out Nacos Client It provides the ability of load balancing , And load balancing algorithm This is exactly what we want to select instances based on weights !
Code in com.alibaba.nacos.api.naming.NamingService#selectOneHealthyInstance , Just find a way to call this line of code , We can realize the functions we want !
Code :
@Slf4j
public class NacosWeightRandomV2Rule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Override
public Server choose(Object key) {
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();
try {
Instance instance = discoveryProperties.namingServiceInstance()
.selectOneHealthyInstance(name);
log.info(" Selected instance = {}", instance);
/*
* instance turn server The logical reference of is from :
* org.springframework.cloud.alibaba.nacos.ribbon.NacosServerList.instancesToServerList
*/
return new NacosServer(instance);
} catch (NacosException e) {
log.error(" Something goes wrong ", e);
return null;
}
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
programme 3: The most violent way to play
Ideas :
In the process of reading the source code , Find the following code :
// come from :org.springframework.cloud.alibaba.nacos.ribbon.NacosServerList#getServers
private List<NacosServer> getServers() {
try {
List<Instance> instances = discoveryProperties.namingServiceInstance()
.selectInstances(serviceId, true);
return instancesToServerList(instances);
}
catch (Exception e) {
throw new IllegalStateException(
"Can not get service instances from nacos, serviceId=" + serviceId,
e);
}
}
This NacosServerList Just give Ribbon To do load balancing ” data source ”! If you change the code here to com.alibaba.nacos.api.naming.NamingService#selectOneHealthyInstance It can also realize the functions we want ?
in other words , hand Ribbon Of List Always only 1 An example ! So no matter Ribbon What kind of load balancing , It's all up to him .
Code :
1 Reference resources NacosServerList Code for , rewrite NacosRibbonServerList
/**
* Reference resources org.springframework.cloud.alibaba.nacos.ribbon.NacosServerList
*/
@Slf4j
public class NacosRibbonServerList extends AbstractServerList<NacosServer> {
private NacosDiscoveryProperties discoveryProperties;
private String serviceId;
public NacosRibbonServerList(NacosDiscoveryProperties discoveryProperties) {
this.discoveryProperties = discoveryProperties;
}
@Override
public List<NacosServer> getInitialListOfServers() {
return getServers();
}
@Override
public List<NacosServer> getUpdatedListOfServers() {
return getServers();
}
private List<NacosServer> getServers() {
try {
Instance instance = discoveryProperties.namingServiceInstance()
.selectOneHealthyInstance(serviceId, true);
log.debug(" Select the instance = {}", instance);
return instancesToServerList(
Lists.newArrayList(instance)
);
} catch (Exception e) {
throw new IllegalStateException(
"Can not get service instances from nacos, serviceId=" + serviceId,
e);
}
}
private List<NacosServer> instancesToServerList(List<Instance> instances) {
List<NacosServer> result = new ArrayList<>();
if (null == instances) {
return result;
}
for (Instance instance : instances) {
result.add(new NacosServer(instance));
}
return result;
}
public String getServiceId() {
return serviceId;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
this.serviceId = iClientConfig.getClientName();
}
}
2 Write configuration classes
/**
* Reference resources :org.springframework.cloud.alibaba.nacos.ribbon.NacosRibbonClientConfiguration
*/
@Configuration
public class NacosRibbonClientExtendConfiguration {
@Bean
public ServerList<?> ribbonServerList(IClientConfig config, NacosDiscoveryProperties nacosDiscoveryProperties) {
NacosRibbonServerList serverList = new NacosRibbonServerList(nacosDiscoveryProperties);
serverList.initWithNiwsConfig(config);
return serverList;
}
}
3 adding annotations , Let's go to the top NacosRibbonClientExtendConfiguration Become Ribbon Default configuration .
// ... Other notes
@RibbonClients(defaultConfiguration = NacosRibbonClientExtendConfiguration.class)
public class ConsumerMovieApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerMovieApplication.class, args);
}
}
Be careful :
Be sure to pay attention to , take NacosRibbonClientExtendConfiguration Put it in ComponentScan Context ( The default is the package of the startup class and its child packages ) outside !!!
Summary and contrast
- programme 1: Is the easiest way to think of playing .
- programme 2: It is my favorite plan at present . First, it's simple , And they are all reused Nacos/Ribbon Existing code —— and Ribbon/Nacos They all come from the production environment of large companies , After rigorous production tests .
- programme 3: It's too violent , hold Ribbon Overhead . This scenario , Throw to Ribbon When making load balancing choices ,List Only 1 Elements , No matter what algorithm is used to calculate , This element is always returned in the end !
reflection
since Nacos Client Already have the ability of load balancing ,Spring Cloud Alibaba Why should we integrate Ribbon Well ?
Personally think that , This is mainly to comply with Spring Cloud standard .Spring Cloud Commons There are subprojects
spring-cloud-loadbalancer, The project has developed standards , Used to adapt various client load balancers ( Although the current implementation only Ribbon, but Hoxton There will be alternative implementations ).Spring Cloud Alibaba This standard has been followed , So integrated Ribbon, Instead of using Nacos Client Load balancing capabilities provided .
边栏推荐
- The road to systematic construction of geek planet business monitoring and alarm system
- [proteus simulation] 74LS138 decoder water lamp
- MYSQL 几个常用命令使用
- 讲真,Kotlin 协程的挂起没那么神秘(原理篇)
- A detailed solution to mysql8.0 forgetting password
- LORA技术---LoRa信号从数据流变为LoRa扩频信号,再从射频信号通过解调变为数据
- R language universalbank CSV "data analysis
- Introduction to JWT
- Oh, my God, it's a counter attack by eight part essay
- Introduction of Neural Network (BP) in Intelligent Computing
猜你喜欢

Simple integration of client go gin 11 delete

一文搞懂 MySQL 中 like 的索引情况

Software testing - Test Case Design & detailed explanation of test classification

Understand the index of like in MySQL

what? You can't be separated by wechat

底部菜单添加的链接无法跳转到二级页面的问题

Overview of common loss functions for in-depth learning: basic forms, principles and characteristics
Summary of 2019: 31 is just another start
Code to Image Converter | 代码生成漂亮图片工具

MySQL foundation - constraints
随机推荐
字节跳动提出轻量级高效新型网络MoCoViT,在分类、检测等CV任务上性能优于GhostNet、MobileNetV3!...
Precautions for Apollo use
Stochastic Adaptive Dynamics of a Simple Market as a Non-Stationary Multi-Armed Bandit Problem
R language organdata dataset visualization
Can financial products be redeemed on weekends?
A Dynamic Near-Optimal Algorithm for Online Linear Programming
Simple integration of client go gin 11 delete
Visualization of wine datasets in R language
慕课6、实现负载均衡-Ribbon
Scheduling with Testing
Introduction to JWT
It supports running in kubernetes, adds multiple connectors, and seatunnel version 2.1.2 is officially released!
Code to Image Converter | 代码生成漂亮图片工具
R语言organdata 数据集可视化
Ribbon负载均衡
模拟串口UART的实现
90-最近优化过的几套Oracle数据库回顾
Xunrui CMS custom data interface PHP executable code
MySQL foundation - constraints
迅睿CMS 自定义数据接口-php执行文件代码