扩展Ribbon:支持Nacos集群配置
TIPS
本文所讲已给Spring Cloud Alibaba提交PR,并已被合并。详见:
https://github.com/spring-cloud-incubator/spring-cloud-alibaba/pull/720
在Nacos上,支持集群配置。集群是对指定微服务的一种虚拟分类。集群还是比较有用的,例如:
•为了容灾,把指定微服务同时部署在两个机房(例如同城多活、异地多活),比如南京机房和北京机房。
•调用时,可优先调用同机房的实例,如果同机房没有实例,再跨机房调用。
当然cluster还有很多其他作用,请各位看客自行脑补,本文将围绕上面描述的场景展开。
虽然Spring Cloud Alibaba支持集群配置,例如:
spring:cloud:nacos:discovery:# 北京机房集群cluster-name: BJ
但在调用时,服务消费者并不会优先调用同集群的实例。
本节来探讨如何扩展Ribbon,从而实现同集群优先调用的效果,并且还能支持Nacos权重配置。关于权重配置,在 一文中已经写得比较详细了。本文在前面的基础上实现同集群优先策略。
写代码
/*** 支持优先调用同集群实例的ribbon负载均衡规则.** @author itmuch.com*/@Slf4jpublic class NacosRule extends AbstractLoadBalancerRule {@Autowiredprivate NacosDiscoveryProperties nacosDiscoveryProperties;@Overridepublic 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;}}@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {}}
负载均衡算法:
// 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);}}
写配置
microservice-provider-user:ribbon:NFLoadBalancerRuleClassName: com.itmuch.cloud.study.ribbon.NacosClusterAwareWeightedRule
这样,服务在调用microservice-provider-user 这个服务时,就会优先选择相同集群下的实例。
配套代码
•GitHub[1]•Gitee[2]
干货分享
•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术讨论群
往期精彩
••••••
References
[1] GitHub: https://github.com/eacdy/spring-cloud-study/tree/master/2019-Spring-Cloud-Alibaba/microservice-consumer-movie-ribbon-rule-with-nacos-2[2] Gitee: https://gitee.com/itmuch/spring-cloud-study/tree/master/2019-Spring-Cloud-Alibaba/microservice-consumer-movie-ribbon-rule-with-nacos-2
想知道更多?长按/扫码关注我吧↓↓↓喜欢就点个"在看"呗^_^
