扩展Ribbon-同集群下优先调用

本文档介绍了如何创建一个名为NacosSameClusterWeightedRule的类,该类实现了Spring Cloud Alibaba Nacos中的一种负载均衡策略。该策略确保在多个集群部署的微服务间,同一集群内的应用优先进行互相调用。通过获取Nacos服务发现的实例,筛选同一集群的实例,并使用Nacos的权重负载均衡算法选择服务实例。
摘要由CSDN通过智能技术生成


前言

假设有两个微服务一个叫user-center ,一个叫content-center。为了容灾,两个微服务在BJ集群和CD集群都有部署。
且要求同一集群下的应用优先调用,也就是说:content-center如果在BJ集群里那么在调用user-center微服务时优先调用BJ集群下的content-center。 下面来实现。

一、创建一个类NacosSameClusterWeightedRule

这个类要干的事情:
//1.拿到loadBalancer
//2.拿到请求的微服务的名称
//3.用 nacosDiscoveryProperties 拿到服务发现的相关API 以及配置文件中配置的集群名字
//4.用 NocasApi 获取这个微服务的所有实例 A
//5.筛选同集群下的微服务实例集合B
//6.B空用A,否则用B
//7.用Nocas 权重负载均衡

二、代码:


import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public class NacosSameClusterWeightedRule extends AbstractLoadBalancerRule {

    @Autowired
    NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {

        try {
            //1.拿到loadBalancer
            BaseLoadBalancer loadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
            //2.拿到请求的微服务的名称
            String name = loadBalancer.getName();
            //3.用 nacosDiscoveryProperties 拿到服务发现的相关API 以及配置文件中配置的集群名字
            NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
            String clusterName = nacosDiscoveryProperties.getClusterName();
            //4.用 NocasApi 获取这个微服务的所有实例 A
            List<Instance> instances = namingService.selectInstances(name, true);
            //5.筛选同集群下的微服务实例集合B
            List<Instance> sameClusterInstances  = instances.stream().filter(instance -> Objects.equals(instance.getClusterName(), clusterName)).collect(Collectors.toList());
            //6.B空用A,否则用B
            List<Instance> instancesToBeChosen = new ArrayList<>();
            if(CollectionUtils.isEmpty(sameClusterInstances)){
                log.warn("发生跨集群的调用,instance name:{} clusterName:{}",name,clusterName);
                instancesToBeChosen = instances;
            }else{
                instancesToBeChosen = sameClusterInstances;
            }
            //7.用NocasApi 权重负载均衡
            Instance instance = Balancer_local.getHostByRandomWeight_local(instancesToBeChosen);
            log.info("NacosSameClusterWeightedRule.instance:url:{},port:{}",instance.getIp(),instance.getPort());
            return new NacosServer(instance);
        } catch (NacosException e) {
            log.error("NacosSameClusterWeightedRule.NacosException:",e);
            e.printStackTrace();
        }
        return null;
    }
}
// 根据 Instance instance = namingService.selectOneHealthyInstance(name);
// 此方法可以根据一个微服务的名字找到其所有节点,然后用权重算法选一个返回。
// 可见这个方法里面一定有一个子方法是:传一个List<Instance> 选节点的方法,我们可以拿来用。
// 源码找到 getHostByRandomWeight(List<Instance> hosts)
// 如果想用源码且不是public的,我们可以自己写个类继承一下,字类就可以调用父类的方法了。
class Balancer_local extends Balancer {
    public static  Instance  getHostByRandomWeight_local(List<Instance> hosts){
        return getHostByRandomWeight(hosts);
    }
}

注意:spring-cloud-alibaba的版本

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>0.9.0.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值