Fork me on GitHub

扩展Ribbon支持Nacos集群配置

在Nacos上,支持集群配置。集群是对指定微服务的一种虚拟分类。集群还是比较有用的,例如:

  • 为了容灾,把指定微服务同时部署在两个机房(例如同城多活【其中1个机房崩溃另一个机房还能顶】、异地多活【防止自然灾害,例如地震什么的】),比如南京机房和北京机房。
    • 调用时,可优先调用同机房的实例,如果同机房没有实例,再跨机房调用。

当然cluster还有很多其他作用,请各位看客自行脑补,本文将围绕上面描述的场景展开。

虽然Spring Cloud Alibaba支持集群配置,例如:

1
2
3
4
5
6
spring:
cloud:
nacos:
discovery:
# 北京机房集群
cluster-name: BJ

但在调用时,服务消费者并不会优先调用同集群的实例。

本节来探讨如何扩展Ribbon,从而实现同集群优先调用的效果,并且还能支持Nacos权重配置。关于权重配置,在 扩展Ribbon支持Nacos权重的三种方式 一文中已经写得比较详细了。本文在前面的基础上实现同集群优先策略。

写代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* 支持优先调用同集群实例的ribbon负载均衡规则.
*
* @author itmuch.com
*/
@Slf4j
public class NacosRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;

@Override
public Server choose(Object key) {
try {
String clusterName = this.nacosDiscoveryProperties.getClusterName();
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();

NamingService namingService = this.nacosDiscoveryProperties.namingServiceInstance();

List<Instance> instances = namingService.selectInstances(name, true);
if (CollectionUtils.isEmpty(instances)) {
return null;
}

List<Instance> instancesToChoose = instances;
if (StringUtils.isNotBlank(clusterName)) {
List<Instance> sameClusterInstances = instances.stream()
.filter(instance -> Objects.equals(clusterName, instance.getClusterName()))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(sameClusterInstances)) {
instancesToChoose = sameClusterInstances;
} else {
log.warn("发生跨集群的调用,name = {}, clusterName = {}, instance = {}", name, clusterName, instances);
}
}

Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose);

return new NacosServer(instance);
} catch (Exception e) {
log.warn("NacosRule发生异常", e);
return null;
}
}

@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}

负载均衡算法:

1
2
3
4
5
6
7
8
9
10
11
12
// Balancer来自于com.alibaba.nacos.client.naming.core.Balancer,也就是Nacos Client自带的基于权重的负载均衡算法。
public class ExtendBalancer extends Balancer {
/**
* 根据权重,随机选择实例
*
* @param instances 实例列表
* @return 选择的实例
*/
public static Instance getHostByRandomWeight2(List<Instance> instances) {
return getHostByRandomWeight(instances);
}
}

写配置

1
2
3
microservice-provider-user:
ribbon:
NFLoadBalancerRuleClassName: com.itmuch.cloud.study.ribbon.NacosClusterAwareWeightedRule

这样,服务在调用microservice-provider-user 这个服务时,就会优先选择相同集群下的实例。

配套代码

相关文章

评论系统未开启,无法评论!