前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >扩展Ribbon:支持Nacos集群配置

扩展Ribbon:支持Nacos集群配置

作者头像
用户1516716
发布2019-07-10 15:52:56
1.4K0
发布2019-07-10 15:52:56
举报
文章被收录于专栏:A周立SpringCloudA周立SpringCloud

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

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

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

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

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

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

代码语言:javascript
复制
spring:
  cloud:
    nacos:
      discovery:
        # 北京机房集群
        cluster-name: BJ

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

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

写代码

代码语言:javascript
复制
/**
 * 支持优先调用同集群实例的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) {
    }
}

负载均衡算法:

代码语言:javascript
复制
// 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);
    }
}

写配置

代码语言:javascript
复制
microservice-provider-user:
  ribbon:
    NFLoadBalancerRuleClassName: com.itmuch.cloud.study.ribbon.NacosClusterAwareWeightedRule

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

配套代码

•GitHub[1]•Gitee[2]

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT牧场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写代码
  • 写配置
  • 配套代码
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档