微服务技术栈-Ribbon负载均衡和Nacos注册中心

文章目录


前言

在上面那个文章中介绍了微服务架构的概念以及eureka注册中心的概念,在本节中我们将继续介绍微服务技术栈的其他两个组件Ribbon和Nacos。


一、Ribbon负载均衡

1.LoadBalancerInterceptor(负载均衡拦截器)

在上篇文章中讲到,Spring会自动帮助我们从eureka-server端,根据userservice这个服务名称,获取实例列表,而后完成负载均衡。

那么这个负载均衡底层 是由谁帮助我们完成的呢?为什么发出的请求明明是http://userservice/user/1 ,怎么变成了**http://localhost:8081/user/1**的呢?

解答:SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。

接下来我们在源码中追踪一下负载均衡功能的具体实现。

底层源码:

  • request.getURI():获取请求uri,本例中就是 http://user-service/user/8
  • originalUri.getHost():获取uri路径的主机名,其实就是服务id,user-service
  • this.loadBalancer.execute():处理服务id,和用户请求。

this.loadBalancer是LoadBalancerClient类型,我们继续跟入execute方法。

  • getLoadBalancer(serviceId):根据服务id获取ILoadBalancer,而ILoadBalancer会拿着服务id去eureka中获取服务列表并保存起来。
  • getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个。

2.负载均衡策略IRule

从上面的源码可以看出getServer(loadBalancer)方法利用内置的负载均衡算法,从服务列表中选择一个。

继续追踪chooseServer方法,发现里面有个rule。
这里的rule默认值是一个RoundRobinRule,看类的介绍:

RoundRobinRule()是轮询的意思,到这里,整个负载均衡的流程我们就清楚了。

总结:SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址做了修改。

负载均衡的规则都定义在IRule接口中,接下来我们来研究一下IRule接口。

IRule接口有很多不同的实现类,不同实现类的含义不同,默认的实现就是ZoneAvoidanceRule,是一种轮询方案

如果我们要更改负载均衡策略,即自定义负载均衡策略,我们要怎么办?

1.代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:

java 复制代码
@Bean
public IRule randomRule(){
    return new RandomRule();
}

2.配置文件方式 :在order-service的application.yml文件中,添加新的配置也可以修改规则

yaml 复制代码
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则 

二、Nacos注册中心

1.Nacos简介

在上篇文章中已经介绍了eureka这个注册中心,现在来介绍另外一个注册中心Nacos。Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka,Ncaos功能更加丰富,在国内受欢迎程度较高。

Nacos是SpringCloudAlibaba的组件,而SpringCloudAlibaba也遵循SpringCloud中定义的服务注册、服务发现规范。因此使用Nacos和使用Eureka对于微服务来说,并没有太大区别。主要差异在于依赖不同和服务地址不同。

2.搭建Nacos注册中心

1)引入依赖

在cloud-demo父工程的pom文件中的<dependencyManagement>中引入SpringCloudAlibaba的依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

在user-service和order-service中的pom文件中引入nacos-discovery依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)配置nacos地址
在user-service和order-service的application.yml中添加nacos地址:

yaml 复制代码
spring:
  cloud:
    nacos:
      server-addr: localhost:8848

重启微服务后,登录nacos管理页面,在服务列表可以查看服务信息。

3.服务分级存储模型

一个服务 可以有多个实例 ,假如这些实例分布于全国各地的不同机房,nacos就将同一机房内的实例划分为一个集群

微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群。修改application.yml文件,添加集群配置。

yaml 复制代码
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ

默认的ZoneAvoidanceRule并不能实现根据同集群优先来实现负载均衡。因此Nacos中提供了一个NacosRule的实现,可以优先从同集群中挑选实例。

yaml 复制代码
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则

因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。在nacos控制台,找到实例列表,点击编辑,即可修改权重。(如果权重修改为0,则该实例永远不会被访问)

4.环境隔离

Nacos提供了namespace来实现环境隔离功能:
1.nacos中可以有多个namespace。
2.namespace下可以有group、service等。
3.不同namespace之间相互隔离,例如不同namespace的服务互相不可见。

给微服务配置namespace只能通过修改配置来实现。例如,修改application.yml文件,指定命名空间。

yaml 复制代码
spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ
        namespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f9 

如果order-service和userservice在不同的命名空间下,此时访问order-service,因为namespace不同,会导致找不到。

5.Nacos与Eureka的区别

Nacos的服务实例分为两种类型:

1.临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
2.非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

yaml 复制代码
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ
        ephemeral: false  #设置为非临时实例

Nacos和Eureka整体结构类似,服务注册、服务拉取、心跳等待。

1.Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式(亲儿子)

2.临时实例心跳不正常会被剔除,非临时实例则不会被剔除。

3.Nacos支持服务列表变更的消息推送模式 ,服务列表更新更及时。


总结

Nacos和Eureka整体结构类似,都支持服务注册和服务拉取以及服务提供者心跳方式做健康检测,但是也存在一些差异。在后续的文章中我们将学习更多有关nacos的知识,包括统一配置中心,热更新以及nacos集群。


相关推荐
攸攸太上2 小时前
JMeter学习
java·后端·学习·jmeter·微服务
妍妍的宝贝3 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
架构师吕师傅5 小时前
性能优化实战(三):缓存为王-面向缓存的设计
后端·微服务·架构
叶北辰CHINA6 小时前
nginx反向代理,负载均衡,HTTP配置简述(说人话)
linux·运维·nginx·http·云原生·https·负载均衡
王彬泽7 小时前
【微服务】服务注册与发现、分布式配置管理 - Nacos
微服务·服务注册与发现·分布式配置管理
攸攸太上17 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
一直在进步的派大星20 小时前
Docker 从安装到实战
java·运维·docker·微服务·容器
Gogeof1 天前
云原生化 - 基础镜像(简约版)
微服务·云原生·基础镜像
Gogeof1 天前
云原生化 - 旅程(简约版)
微服务·云原生
王彬泽1 天前
【微服务】负载均衡 - LoadBalance(day4)
微服务·负载均衡