【Spring Cloud】Nacos服务分级存储模型与负载均衡原理与实战




1. 服务分级模型介绍

image-20221123164407092

  • 为了提升整个系统的容灾性,Nacos 引入了地域 (Zone) 的概念,如上图中的北京、上海和杭州。把同一个服务的多个实例部署到不同地域的机房中 (鸡蛋分开不同的篮子放) ;又把在同一个地域的机房的多个服务实例称为集群 (Cluster) 。比如,杭州机房的 2 个用户服务 user-service 称为杭州 user-service 集群。
  • 因此,在 Nacos 的服务分级模型中,
    • 第一级是微服务 (如订单服务) ;
    • 第二级是集群 (如北京订单服务集群、上海订单服务集群等) ;
    • 第三集是实例 (如杭州服务集群的 8081 端口实例、8082 端口实例等) 。

2. 服务分级模型的必要性

  • 微服务之间的远程调用要优先调用同一个地域的集群中的实例,因为访问同一个集群中的服务距离较短、速度比较快、延迟比较低 (例如北京集群的订单服务调用北京集群的用户服务) 。而跨地域集群地域距离远、速度慢、延迟高 (例如北京集群的订单服务调用上海集群的用户服务) 。

  • 那为什么 Nacos 还要增加一层【集群】的概念呢?

  • 首先就是为了避免跨地域集群的远程调用发生,让微服务之间的远程调用尽可能地发生在同一个地域集群中,保证访问的高速低延迟。其次就是为了当同地域的集群服务不可用时,可以跨地域集群访问,保证服务的高可用,提升系统的容灾能力。

    image-20221218171235828


3. 配置集群属性

  • 首先介绍一下项目微服务结构。微服务层有 2 个,分别是订单微服务 order-service 和用户微服务 user-service ,订单微服务需要远程调用用户微服务;集群层目前没有,是本节我们要构建的;实例层,订单微服务有 1 个实例,而用户微服务有 3 个实例。

    image-20221218172539831

  • 我们把 UserApplication 实例和 UserApplication2 实例设置为青岛 (QD) 机房;把 UserApplication3 设置为北京 (BJ) 机房。来模拟跨集群部署的方式。

  • 修改用户微服务 user-serviceapplication.yml 配置文件,添加以下内容。

    spring: 
      # Nacos配置
      cloud:
        nacos:
          server-addr: 192.168.168.101:8848 # Nacos服务地址
          discovery:
            cluster-name: QD # 地域集群层名称,可自定义,QD代指青岛
    

    设置好青岛集群后,注意,只选择 UserApplication 实例和 UserApplication2 实例启动。

    image-20221218173241797

  • UserApplication 实例和 UserApplication2 实例启动完成后,再回去用户微服务 user-serviceapplication.yml 配置文件,把地域集群名称由 QD 改为 BJ

    spring: 
      # Nacos配置
      cloud:
        nacos:
          server-addr: 192.168.168.101:8848 # Nacos服务地址
          discovery:
            cluster-name: BJ # 地域集群层名称,可自定义,BJ代指北京
    

    设置好北京集群后,注意,只选择 UserApplication3 实例启动。

    image-20221218173608268

  • 此时,打开 Nacos 控制台主页,可以看到用户服务 userservice 【集群数目】已经变为 2 了。

    image-20221218173836825

  • 点进【详情】查看。可以看到分为了 QDBJ 两个集群,QD 集群下有 2 个用户微服务实例;而 BJ 集群下有 1 个用户微服务实例。说明 Nacos 服务分级模型配置成功。

    image-20221218174010850


4. NacosRule负载均衡


4.1 背景描述

  • 上节我们给用户微服务 user-service 配置了青岛和北京 2 个集群。我们说过,Nacos 增加【集群】这一层是为了确保微服务间远程调用尽可能地在同一地域的集群中发生,避免跨集群的远程调用。这一节我们来做个实验,让用户微服务 user-service 作为服务提供者,而订单微服务 order-service 作为服务消费者,修改订单微服务 order-serviceapplication.yml 配置文件,分别配置青岛和北京 2 个集群名称,验证是否能按照【就近原则】优先调用同一个集群的微服务。

  • 打开订单微服务 order-serviceapplication.yml 配置文件,加入以下内容,先配置为青岛集群。

    spring: 
      # Nacos配置
      cloud:
        nacos:
          server-addr: 192.168.168.101:8848 # Nacos服务地址
          discovery:
            cluster-name: QD # 地域集群层名称,可自定义,QD代指青岛
    
  • 然后,启动订单微服务 OrderApplication

    image-20221218181201337

  • 启动完成后,进入 Nacos 控制台主页,看到订单微服务 orderservice 已经成功注册到 Nacos 中了。

    image-20221218175727251

    点击【详情】查看订单微服务 orderservice 所属的集群为青岛集群。

    image-20221218175839653

  • 接下来,我们让订单微服务 OrderApplication 向用户微服务发起远程调用,看看会不会优先调用同在青岛集群的用户微服务实例。

    image-20221218180120547

  • 回到 IDEA 查看用户微服务的 3 个实例的控制台输出,发现 3 个实例都被访问了。这是怎么回事呢?不是说好优先访问同在青岛集群的 8081 和 8082 实例吗?

    image-20221218180422487

  • 这是因为,依然采用了轮询的负载均衡策略。我们需要配置成 Nacos 的负载均衡策略。


4.2 配置Nacos负载均衡策略

  • 打开订单微服务 order-serviceapplication.yml 配置文件,加入以下内容,配置负载均衡策略为 NacosRule ,这个策略会优先访问与自己在同一个集群下的微服务,然后在同一个集群内的实例再采用随机策略来做负载均衡。

    userservice:
      ribbon:
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule  # 负载均衡策略
    
  • 然后重启订单微服务 OrderApplication 生效。

    image-20221218181201337

  • 用 Postman 测试。

    image-20221218180120547

  • 回到 IDEA 查看用户微服务的 3 个实例的控制台输出,发现北京集群的用户服务 8083 没有被访问到,而同在青岛集群的 8081 和 8082 则被访问到了。说明 NacosRule 负载均衡策略的确优先选择同一个地域的集群来访问,实现【就近原则】。此外,在同一集群的多个实例内是采取随机策略的,8082 只被访问到 1 次,而 8081 则被访问到 5 次,可见在同一集群的多个实例并不是采用轮询策略。

    image-20221218181534815

    image-20221218181730414

    image-20221218181750610

  • 此时把青岛集群的 2 个用户微服务实例 8081 和 8082 停掉,那么订单微服务就不得不跨地域集群去访问北京集群的用户服务实例 8083 了。

    image-20221218182308625

    image-20221218180120547

    image-20221218182431280

  • 而在订单微服务的控制台中,就会发出警告:发生了一起跨集群调用。方便运维工程师排查和修复。

    image-20221218182744653


4.3 根据权重负载均衡

  • 针对公司服务器性能水平参差不齐的情况,我们希望性能强的服务器承担更多的微服务远程调用,而性能稍弱的微服务承担较少的访问,从而最大限度地发挥服务器的最佳性能和利用率。但目前 NacosRule 的策略是集群优先,然后随机,这无法满足上述需求。

  • 因此,Nacos 提供了权重 (值域 0~1) 配置来控制访问频率,权重越大的服务器则访问频率越高。当权重调为 0 时就不会被访问,可以做无感知的停机升级和灰度测试。

  • 进入 Nacos 控制台主页,进入用户服务 userservice 【详情】,默认权重都为 1 。现在假设 8081 是性能强的服务器,8082 是性能弱的服务器,因此把 8081 的权重设置得大一些,而 8082 的权重设置得小一些。

    image-20221218184128145

  • 点击右侧的【编辑】,把 8082 的权重设为 0.1 。

    image-20221218184350355

  • 这样,8081 被访问到的概率就应该是 8082 的 10 倍。

    image-20221218184609258

  • 我们用 Postman 测试一下。结果是我试了 20 几次,只有 1 次访问到 8082 ,其余都访问到 8081 了。说明权重生效。

猜你喜欢

转载自blog.csdn.net/Sihang_Xie/article/details/128364794
今日推荐