美文网首页
扩展Ribbon-支持同集群优先

扩展Ribbon-支持同集群优先

作者: 初心myp | 来源:发表于2019-08-15 17:31 被阅读0次

    实现优先调用统一集群的实例。

    案例:为了容灾,我们将内容中心和用户中心都部署在了北京机房和南京机房,为了实现提升性能,我希望实现同机房优先调用,也就是说北京机房的内容中心优先调用北京机房的用户中心实例,如果北京机房找不到任何用户中心的实例,才考虑调用南京机房的实例。为了实现这个目标,我们使用nacos的cluster就非常的方便。不了解nacos的cluster的可以先看一下文章:服务发现(nacos组件)中的nacos服务发现的领域模型。接下来我们代码实现一下:

    package com.chuxin.contentcenter.config;
    
    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;
    
    /**
     * @FileName: NacosSameClusterWeightedRule
     * @Description: 实现同一集群优先调用
     * @author: <a href="mailto: muyuanpei@camelotchina.com">myp</a>
     * @create: 2019-08-15 16:07
     */
    @Slf4j
    public class NacosSameClusterWeightedRule extends AbstractLoadBalancerRule {
    
        @Autowired
        private NacosDiscoveryProperties nacosDiscoveryProperties;
    
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
    
        }
    
        /**
        * 实现步骤:
        * 1.找到指定服务的所有实例
        * 2.过滤出相同集群下的所有实例
        * 3.如果上述2为空,就用1
        * 4.基于权重的负载均衡算法,返回一个实例
        */
        @Override
        public Server choose(Object key) {
            try {
                //获取到配置中的集群名称
                String clusterName = nacosDiscoveryProperties.getClusterName();
    
                BaseLoadBalancer loadBalancer = (BaseLoadBalancer)this.getLoadBalancer();
    
                //想要请求的微服务的名称
                String name = loadBalancer.getName();
                //拿到服务发现的相关API
                NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
    
                //1.找到指定服务的所有实例
                List<Instance> instances = namingService.selectInstances(name, true);
    
                //2.过滤出相同集群下的所有实例
                List<Instance> sameClusterInstances = instances.stream()
                        .filter(instance -> Objects.equals(instance.getClusterName(), clusterName))
                        .collect(Collectors.toList());
    
                // 3.如果上述2为空,就用1
                List<Instance> instancesToBeChosen = new ArrayList<>();
                if (CollectionUtils.isEmpty(sameClusterInstances)){
                    instancesToBeChosen = instances;
                    log.warn("发生了跨集群的调用,name = {}, clusterName = {}, instances = {}",name,clusterName,instances);
                } else {
                    instancesToBeChosen = sameClusterInstances;
                }
    
                //4.基于权重的负载均衡算法,返回一个实例
                Instance instance = ExtendsBalancer.getHostByRandomWeightExtends(instancesToBeChosen);
                log.info("选择的实例是  instance = {}",instance);
                return new NacosServer(instance);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
    
        }
    }
    
    class ExtendsBalancer extends Balancer {
        public static Instance getHostByRandomWeightExtends(List<Instance> hosts) {
            return getHostByRandomWeight(hosts);
        }
    }
    

    全局配置类添加的信息

        @Bean
        public IRule ribbonRule() {
    
            // 使用自定义负载均衡规则(支持nacos设置权重的负载均衡规则,同集群优先调用)
            return new NacosSameClusterWeightedRule();
        }
    

    配置文件中配置集群名称(每个结点都需要指定):

    spring:
      cloud:
        nacos:
          discovery:
            # 指定集群名称
            cluster-name: BJ
    

    这样就OK了。。。

    相关文章

      网友评论

          本文标题:扩展Ribbon-支持同集群优先

          本文链接:https://www.haomeiwen.com/subject/lwzzjctx.html