扩展Ribbon:支持Nacos集群配置

点击上方"IT牧场",选择"设为星标"技术干货每日送达!

TIPS

本文所讲已给Spring Cloud Alibaba提交PR,并已被合并。详见:https://github.com/spring-cloud-incubator/spring-cloud-alibaba/pull/720

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

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

•调用时,可优先调用同机房的实例,如果同机房没有实例,再跨机房调用。


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

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

 
 
spring:	
  cloud:	
    nacos:	
      discovery:	
        # 北京机房集群	
        cluster-name: BJ

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

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

写代码

 
 
/**	
 * 支持优先调用同集群实例的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) {	
    }	
}

负载均衡算法:

 
 
// 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]

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!

•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术讨论群

往期精彩

扩展Ribbon支持Nacos权重的三种方式e.printStackTrace()不是打印吗,还能锁死?一次 MySQL 千万级大表的优化过程高级 Java 程序猿必须掌握的 17 个 JVM 参数日志打印的正确姿势!重构一时爽,构错火葬场

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


想知道更多?长按/扫码关注我吧↓↓↓640?wx_fmt=jpeg>>>技术讨论群<<<喜欢就点个"在看"呗^_^

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值