![](https://i-blog.csdnimg.cn/blog_migrate/dd81f80e91ac200afb635a9cdfaf2e1d.png)
1. 服务分级模型介绍
- 为了提升整个系统的容灾性,Nacos 引入了地域 (Zone) 的概念,如上图中的北京、上海和杭州。把同一个服务的多个实例部署到不同地域的机房中 (鸡蛋分开不同的篮子放) ;又把在同一个地域的机房的多个服务实例称为集群 (Cluster) 。比如,杭州机房的 2 个用户服务
user-service
称为杭州user-service
集群。 - 因此,在 Nacos 的服务分级模型中,
- 第一级是微服务 (如订单服务) ;
- 第二级是集群 (如北京订单服务集群、上海订单服务集群等) ;
- 第三集是实例 (如杭州服务集群的 8081 端口实例、8082 端口实例等) 。
2. 服务分级模型的必要性
-
微服务之间的远程调用要优先调用同一个地域的集群中的实例,因为访问同一个集群中的服务距离较短、速度比较快、延迟比较低 (例如北京集群的订单服务调用北京集群的用户服务) 。而跨地域集群地域距离远、速度慢、延迟高 (例如北京集群的订单服务调用上海集群的用户服务) 。
-
那为什么 Nacos 还要增加一层【集群】的概念呢?
-
首先就是为了避免跨地域集群的远程调用发生,让微服务之间的远程调用尽可能地发生在同一个地域集群中,保证访问的高速低延迟。其次就是为了当同地域的集群服务不可用时,可以跨地域集群访问,保证服务的高可用,提升系统的容灾能力。
3. 配置集群属性
-
首先介绍一下项目微服务结构。微服务层有 2 个,分别是订单微服务
order-service
和用户微服务user-service
,订单微服务需要远程调用用户微服务;集群层目前没有,是本节我们要构建的;实例层,订单微服务有 1 个实例,而用户微服务有 3 个实例。 -
我们把
UserApplication
实例和UserApplication2
实例设置为青岛 (QD) 机房;把UserApplication3
设置为北京 (BJ) 机房。来模拟跨集群部署的方式。 -
修改用户微服务
user-service
的application.yml
配置文件,添加以下内容。spring: # Nacos配置 cloud: nacos: server-addr: 192.168.168.101:8848 # Nacos服务地址 discovery: cluster-name: QD # 地域集群层名称,可自定义,QD代指青岛
设置好青岛集群后,注意,只选择
UserApplication
实例和UserApplication2
实例启动。 -
UserApplication
实例和UserApplication2
实例启动完成后,再回去用户微服务user-service
的application.yml
配置文件,把地域集群名称由QD
改为BJ
。spring: # Nacos配置 cloud: nacos: server-addr: 192.168.168.101:8848 # Nacos服务地址 discovery: cluster-name: BJ # 地域集群层名称,可自定义,BJ代指北京
设置好北京集群后,注意,只选择
UserApplication3
实例启动。 -
此时,打开 Nacos 控制台主页,可以看到用户服务
userservice
【集群数目】已经变为 2 了。 -
点进【详情】查看。可以看到分为了
QD
和BJ
两个集群,QD
集群下有 2 个用户微服务实例;而BJ
集群下有 1 个用户微服务实例。说明 Nacos 服务分级模型配置成功。
4. NacosRule负载均衡
4.1 背景描述
-
上节我们给用户微服务
user-service
配置了青岛和北京 2 个集群。我们说过,Nacos 增加【集群】这一层是为了确保微服务间远程调用尽可能地在同一地域的集群中发生,避免跨集群的远程调用。这一节我们来做个实验,让用户微服务user-service
作为服务提供者,而订单微服务order-service
作为服务消费者,修改订单微服务order-service
的application.yml
配置文件,分别配置青岛和北京 2 个集群名称,验证是否能按照【就近原则】优先调用同一个集群的微服务。 -
打开订单微服务
order-service
的application.yml
配置文件,加入以下内容,先配置为青岛集群。spring: # Nacos配置 cloud: nacos: server-addr: 192.168.168.101:8848 # Nacos服务地址 discovery: cluster-name: QD # 地域集群层名称,可自定义,QD代指青岛
-
然后,启动订单微服务
OrderApplication
。 -
启动完成后,进入 Nacos 控制台主页,看到订单微服务
orderservice
已经成功注册到 Nacos 中了。点击【详情】查看订单微服务
orderservice
所属的集群为青岛集群。 -
接下来,我们让订单微服务
OrderApplication
向用户微服务发起远程调用,看看会不会优先调用同在青岛集群的用户微服务实例。 -
回到 IDEA 查看用户微服务的 3 个实例的控制台输出,发现 3 个实例都被访问了。这是怎么回事呢?不是说好优先访问同在青岛集群的 8081 和 8082 实例吗?
-
这是因为,依然采用了轮询的负载均衡策略。我们需要配置成 Nacos 的负载均衡策略。
4.2 配置Nacos负载均衡策略
-
打开订单微服务
order-service
的application.yml
配置文件,加入以下内容,配置负载均衡策略为NacosRule
,这个策略会优先访问与自己在同一个集群下的微服务,然后在同一个集群内的实例再采用随机策略来做负载均衡。userservice: ribbon: NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡策略
-
然后重启订单微服务
OrderApplication
生效。 -
用 Postman 测试。
-
回到 IDEA 查看用户微服务的 3 个实例的控制台输出,发现北京集群的用户服务 8083 没有被访问到,而同在青岛集群的 8081 和 8082 则被访问到了。说明 NacosRule 负载均衡策略的确优先选择同一个地域的集群来访问,实现【就近原则】。此外,在同一集群的多个实例内是采取随机策略的,8082 只被访问到 1 次,而 8081 则被访问到 5 次,可见在同一集群的多个实例并不是采用轮询策略。
-
此时把青岛集群的 2 个用户微服务实例 8081 和 8082 停掉,那么订单微服务就不得不跨地域集群去访问北京集群的用户服务实例 8083 了。
-
而在订单微服务的控制台中,就会发出警告:发生了一起跨集群调用。方便运维工程师排查和修复。
4.3 根据权重负载均衡
-
针对公司服务器性能水平参差不齐的情况,我们希望性能强的服务器承担更多的微服务远程调用,而性能稍弱的微服务承担较少的访问,从而最大限度地发挥服务器的最佳性能和利用率。但目前 NacosRule 的策略是集群优先,然后随机,这无法满足上述需求。
-
因此,Nacos 提供了权重 (值域 0~1) 配置来控制访问频率,权重越大的服务器则访问频率越高。当权重调为 0 时就不会被访问,可以做无感知的停机升级和灰度测试。
-
进入 Nacos 控制台主页,进入用户服务
userservice
【详情】,默认权重都为 1 。现在假设 8081 是性能强的服务器,8082 是性能弱的服务器,因此把 8081 的权重设置得大一些,而 8082 的权重设置得小一些。 -
点击右侧的【编辑】,把 8082 的权重设为 0.1 。
-
这样,8081 被访问到的概率就应该是 8082 的 10 倍。
-
我们用 Postman 测试一下。结果是我试了 20 几次,只有 1 次访问到 8082 ,其余都访问到 8081 了。说明权重生效。