Nacos-服务多级存储模式 & 集群 & 优先本地集群访问的负载均衡的实现

​ 之前我们有服务的概念,我们提供用户查询的userservice服务,还有提供订单查询的orderservice服务。然后,userservice还部署了多个实例,我们有8081 、8082、8083,这三个呢,都是userservice的实例,所以我们之前是有两层概念的,一层是服务,而第二层就是实例。一个服务,可以包含多个实例。不过呀,随着我们这个业务规模越来越扩大,那么我们就会考虑更多的问题了。比如说我们现在的,我们把所有的实力都部署在一个地方,就像你把鸡蛋都放在一个篮子里,哪天你不小心篮子翻了,那所有的鸡蛋不就都打碎了吗?**那你的机房放在那里同一个地方,哪天天灾人祸出了问题,整个服务不就完了?**所以呀,为了解决这个问l题,我们会将一个服务的多个实例部署到多个机房,特别是像阿里京东这些财大气粗的,哎,我给全国各地,上海、杭州、北京都整一个,这俩送到杭州,这俩到上海,再来几个给它扔到北京,这就像我们把鸡蛋分散开了,一个打了是不是还有好几栏儿呢,对不对?那这样呢,就能够做到一种叫容灾。而我们的那个服务分级存储模型,就是引入了这样一个机房的概念,或者叫地域的概念,把同在一个机房的多个实例称为一个集群。比如,杭州机房的两个userservice实例就称之为杭州的userservice集群,那北京的userservice实例就称为北京的userservice集群。所以呢,在Nacos的服务分级模型中啊,一级是服务,往下是集群,再往下是实例。

​ **那为什么Nacos要引入这样的一个服务分级的?**我原来直接服务找实例不好吗?为什么要多加一个地域划分集群的一个概念?我们设想这么一种情况,比方说我有一个杭州的地方,里面有orderservice的集群,还有一个userservice集群,然后呢,我还有一个上海的地方,也是一样的配置,将来还有广东地方,这个北京地方等等。现在呢,我的orderservice需要访问userservice,那么它有两种选择,一种是在自己本地局域网内访问,另一种是去外边的机房访问。那你觉得他该选哪个呀?那不用说呀,肯定选本地啊,因为外边的野花不要采嘛。当然啦,还有更重要的原因,我们局域网内的访问呢,它的距离比较短,所以呢,速度比较快,延迟比较低,而你跨越了这种集群的访问,比如说你从杭州访问到广州或者北京,那么达到数百公里上千公里,那么这个时候延迟是非常高的,所以啊,在服务调用时,应该尽可能的去访问本地集群,只有在本地集群不可用的情况下,我们才会考虑去访问其集群。我们的Nacos引入这个集训概念,其实就是为了防止出现跨集群调用啊,尽可能的避免。

image-20230208114620776

image-20230208114536926

image-20230208114842391

演示:

image-20230208115409758

image-20230208115731341

然后去Nacos控制台就可以看到有两个集群,以及集群各自有的实例

image-20230208115947584

image-20230208115826327

orderservice想访问本地集群HZ中的userservice的那两个实例服务,那么首先就需要将orderservice也注册到HZ集群

image-20230208120609913

image-20230208120553443

到这个时候,如果orderservice去访问3次userservice服务时,userservice的三个实例都会被访问到,因为依然采用的是轮询的方式。服务在选择实例时的规则都是由负载均衡的规则来决定的,也就是Irule,因为还没有配置Irule,所以还是默认的轮询方式。所以要想实现优先同集群访问的这种负载均衡的规则,我们必须去修改负载均衡。

image-20230208121356082

在orderservice的yml配置文件中:

1
2
3
userservice: # 要做配置的微服务名称
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规矩(优先同集群访问)

这样之后,orderservice去访问多次userservice服务,就会发现都是访问的是8081、8082的实例(在idea的控制台可以看各实例日志,8083是没有日志输出的)。

  • 那么有一个问题,本地同集群的8081、8082两个实例的被访问的比例是怎么的呢?

    • 其实是随机的,NacosRule的一个特点,优先使用本地同集群,在集群内的多个服务当中再采用随机方式来负载均衡
  • 那么又有一个问题,如果我们把orderservice的同集群的userservice服务都停了,这样就只剩下不同集群的SH内的userservice实例,这个时候再去通过oerservice访问userservice时会怎样呢?

image-20230208122809011

image-20230208122900770

这是orderservice去访问userservice就会去跨集群访问了,即访问到8083端口的实例。idea,看一下日志。我们发现,这次请求是8083给承担了,那在order当中会出现一个警告信息什么,显示一次跨集群访问发生了,谁呀?就是userservice,那么你想访问的是杭州,但是呢,实际上你访问的是上海。那通过这个啊,我们就知道了,NacosRule其实优先访问本地,本地没有,它才会跨境访问,跨域访问时,它会有一个警告,将来我们的运维人员如果看到了这样的警告信息,就能够清楚的知道发生了什么问题了,那么他就会及时的去重新启动我们的挂掉的服务,这样问题就能得到解决了

image-20230208123816670