当前位置:网站首页>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 .
边栏推荐
- R language usarrests dataset visualization
- Introduction to async profiler
- MySQL Basics - functions
- Stochastic Adaptive Dynamics of a Simple Market as a Non-Stationary Multi-Armed Bandit Problem
- 密码学系列之:PKI的证书格式表示X.509
- R language organdata dataset visualization
- MySQL中如何计算同比和环比
- Summary of 2019: 31 is just another start
- Easyclick update Gallery
- 慕课5、服务发现-Nacos
猜你喜欢

Visualization of R language nutrient dataset

what? You can't be separated by wechat

Xunrui CMS custom data interface PHP executable code

Three months of self-taught automatic test, salary from 4.5K to 15K, who knows what I have experienced?

智能计算之神经网络(BP)介绍
Code to Image Converter | 代码生成漂亮图片工具

Introduction to async profiler

用RNN & CNN进行情感分析 - PyTorch

深度学习常用损失函数总览:基本形式、原理、特点

Visualization of wine datasets in R language
随机推荐
85-这些SQL调优小'技巧',你学废了吗?
启牛送的券商账户是安全的吗?启牛提供的券商账户是真的?
89-oracle SQL写法与优化器缺陷一例
支持在 Kubernetes 运行,添加多种连接器,SeaTunnel 2.1.2 版本正式发布!
跨域 CORS/OPTIONS
模拟串口UART的实现
[proteus simulation] H-bridge drive DC motor composed of triode + key forward and reverse control
Visualization of R language nutrient dataset
R 语言 wine 数据集可视化
Teach you how to create SSM project structure in idea
Emotion analysis with RNN & CNN pytorch
Cryptography series: certificate format representation of PKI X.509
R language universalbank CSV "data analysis
用RNN & CNN进行情感分析 - PyTorch
【Proteus仿真】8x8Led点阵数字循环显示
Scheduling with Testing
mysql8.0忘记密码的详细解决方法
Nestjs 集成 config module 与 nacos 实现配置化统一
Is the brokerage account of qiniu delivery safe? Is the brokerage account provided by qiniu true?
88-被广为流传的参数优化, 是蜜糖还是毒药?