- 认识和安装Nacos
- Nacos快速入门
- Nacos服务分级存储模型
- Nacos环境隔离
代码获取:1693905917/springCloud: springCloud学习 (github.com)
认识和安装Nacos
认识Nacos
Nacos是阿里巴巴的产品,现在是SpringCloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。
windows版本使用nacos-server-1.4.1.zip包即可。
解压
将这个包解压到任意非中文目录下,如图:
目录说明:
- bin:启动脚本
- conf:配置文件
端口配置
Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。
**如果无法关闭占用8848端口的进程**,也可以进入nacos的conf目录,修改配置文件中的端口:
修改其中的内容:
启动
启动非常简单,进入bin目录,结构如下:
然后执行命令即可:
- windows命令:
startup.cmd -m standalone
执行后的效果如图:
访问
在浏览器输入地址:http://127.0.0.1:8848/nacos即可:
默认的账号和密码都是nacos,进入后:
Nacos快速入门
Nacos与Eureka对于发现客户端与服务注册的接口已经实现了统一遵循SpringCloud所定义好的接口规范:
那么我们在实验Nacos还是Eureka时,我们的服务提供者和消费者的代码是不用做什么变化的,那变化的东西是什么呢?
不清楚什么是Eureka?小编建议: Eureka注册中心-CSDN博客
答:
1. 我们所要用的依赖会改变,之前是引Eureka,现在要引入Nacos的客户端依赖
2.服务地址会改变,之前是配的是Eureka的地址,现在要配的是Nacos的地址
服务注册到Nacos
在完成服务注册与发现前,我们要改依赖,那么改依赖之前,我们会先改父工程的依赖,我们把spring cloud阿里巴巴的管理依赖进来以后,他有关的所有版本我们就不用再操心。
1.在cloud-demo父工程中添加spring-cloud-alilbaba的管理依赖:
<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>
2.注释掉order-service和user-service中原有的eureka依赖。
3.添加nacos的客户端依赖:
<!-- nacos客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
4.修改user-service&order-service中的application.yml文件,注释eureka地址,添加nacos地址:
5.启动并测试:
Nacos就修改以上配置,其他配置基本上与Eureka一模一样不用动。
服务多级存储模型
服务多级存储模型的概念引入:
我们知道的是,一个服务可以有多个实例(这里的实例就是指的是服务器),我们把所有的实力都部署在一个地方,这就像你把鸡蛋放在一个篮子里,哪天你不小心篮子翻了,那所有的蛋不就打了吗?那你的机房放在那里,哪天天灾人祸出了问题,那整个服务不就完了吗?所以为了解决这个问题,我们会将一个服务的多个实例部署到多个机房
服务跨集群调用问题:
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高
本地集群不可访问时,再去访问其它集群
服务集群属性:
如何将每个实例划分成按地域来分级的集群?
答:
1.修改application.yml,添加如下内容:
spring:
cloud:
nacos:
server-addr: localhost:8848 # nacos 服务端地址
discovery:
cluster-name: HZ # 配置集群名称,也就是机房位置,例如:HZ,杭州
在这里我们将实例UserApplication、UserApplication2划分为杭州集群,UserApplication3划分为上海集群。
先将cluster-name:设置为HZ,然后运行实例UserApplication、UserApplication2:
这样实例UserApplication、UserApplication2就划分到了杭州集群中,
然后我们将UserApplication3划为到上海集群,要先将cluster-name:设置为SH,然后运行实例UserApplication3,这样UserApplication3就划分到上海:
注意:运行了运行实例UserApplication3就不要重新运行实例UserApplication、UserApplication2,否则实例UserApplication、UserApplication2就会被划分到上海,而不是杭州集群。
在Nacos控制台可以看到集群变化:
总结:
Nacos服务分级存储模型:
- 一级是服务,例如userservice
- 二级是集群,例如杭州或上海
- 三级是实例,例如杭州机房的某台部署了userservice的服务器
NacosRulet负载均衡
我们上面的操作是将user-service部署到了杭州(HZ)集群,不过呀我们最终想要实现的是order-service远程调用时,优先选择本地集群,因此我们还需要给order-service也置一个集群属性。
服务集群属性
我们现在来创建个案例:先将order-service设置成杭州(HZ)集群,然后开始验证:
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高
本地集群不可访问时,再去访问其它集群
第一步:修改order-service中的application.yml,设置集群为HZ:
此时我们HZ集群有OrderApllication、UserApllication、UserApllication2这三个实例,而SH集群就UserApllication3:
那么我们访问OrderApllication实例来验证:
服务调用尽可能选择本地集群的服务,跨集群调用延迟较高
本地集群不可访问时,再去访问其它集群
但是,你会发现,好像并没有于我们验证的结果相符合,而是访问OrderApllication实例时UserApllication、UserApllication2、UserApllication3都有访问。这是为什么?
答:是因为如果你没有设置访问方式,默认采用的还是轮询访问方式
我们要知道服务在选择实例时,它的规则都是由负载均衡(IRule)来管理,由于我们没有配置负载均衡(IRule)的访问规则,所以默认就是轮询访问方式。所以:
在order-service中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务:
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
Nacos注册中心有个特点:
它优先选择本地集群,在本地集群内的多个服务当中它再采用随机方式进行负载均衡
我们如何模拟实现本地集群都故障,而让本地服务去访问其他地方集群呢?
答:
当我们将我们的UserApllication、UserApllication2实例运行停止,只留OrderApllication、UserApllication3这两个实例时,此时,当OrderApllication实例开始访问时,就会访问UserApllication3实例:
当然我们要知道的是,负载均衡对于选择哪个区域的集群采用的是优先选择同集群服务实例列表,可是在确定好集群后,对于集群中的实例选择还是默认采用随机负载均衡的方式进行挑选。
总结:
服务实例的权重设置
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求
Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高
1.在Nacos控制台可以设置实例的权重值,首先选中实例后面的编辑按钮
2.将权重设置为0.1,测试可以发现8081被访问到的频率大大降低
一般权重值在1~0之间
注意:当某个实例权重值为0时,这个实例压根就不会被访问到:
这样的作用一般应用在我们服务升级时,我们不可能重启服务,这样如果有用户在这个时间正在访问时,效果就不好,所以我们就要应用“使得某个实例权重为0”的技术来避免,让用户感受不到你在升级维护。同时,你也可以把权重从0开始慢慢往上调,放一些用户进来帮我们测试这种升级维护如何。
环境隔离
Nacos中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离
为什么还要有namespace和group这两个,我们之前学习的服务、集群、实例这三级不是够用了吗?
答:注意:之前学习的服务、集群、实例这三级是根据服务划分、实例划分、地域划分。但是实际上,我们还有开发环境、测试环境的划分,所以我们namespace可以做为环境变化来进行划分隔离,至于group:我们可以将业务相关度比较高的服务放在一个group中。
注意:namespace和group没有强制要求一定要设置。
如何设置Namespace?
1.在Nacos控制台可以创建namespace,用来隔离不同环境
2.然后填写一个新的命名空间信息:
3.保存后会在控制台看到这个命名空间的id:
如何将OrderService服务划分到dev命名空间中?
4.修改order-service的application.yml,添加namespace:
5.重启order-service后,再来查看控制台:
6.此时访问order-service的localhost:8080/order/101,因为namespace不同,会导致找不到userservice,控制台会报错:
原因:不同namespace下的服务互相不可见
Nacos和Eureka的对比
nacos注册中心细节分析
不管是什么祥的注册中心,我们服务提供者在启动时都会把自己的信息提交给注册中心,而注册中心就会把这些信息保留下来,那么当我的消费者需要去消费时,他就可以找注册心去要这个服务信息了,称为服务的拉取(服务发现)。注意:
Pull这个动作不是每一次都要做的,你想想,如果我每次发请求时都去做一次拉去,那么这样一来对Eureka注册中心来讲,压力是不是有点太大了,所以作为消费者在做服务拉取时,他会将拉取到的服务信息缓存到个列表当中,那么这样的话,我拉取一次以后,那么接下来一段时间我就以不用去拉取了,而是直接使用列表中的这个缓存里面的列表,那么当然如果我这个缓存一直不更新也不行,万一人家服务信息提供者变化了怎么办呢,所以呢,这个列表会每隔30秒重新去拉取一次进行一次更新,这个缓存操作是Eureka注册中心有的。
而Nacos就不一样,差别在哪里呢?差别在于服务提供者这个健康检测,Nacos会把服务的提供者划分成划分成临时实例和非临时实例:
临时实例和非临时实例:
如果我们不指定实例,默认都是临时实例:
服务注册到Nacos时,可以选择注册为临时或非临时实例,通过下面的配置来设置:
临时实例与非临时实例去做健康检查是不一样的:
对于临时实例来说,将来我们可以人为地把服务停掉,所以Nacos对于临时实例做检查时采用的是心跳检测与Eureka的一样。
对于非临时实例来说,将来我们可以人为地把服务停掉,nacos会主动询问
临时实例宕机时,会从nacos的服务列表中剔除,而非临时实例则不会。
Eureka只能消费者定时30秒主动拉取注册中心的服务集群中最新信息,如果在这30秒内,服务集群已经被改变了,但是消费者这边还要等30秒以后才能获取最新数据,这是一个缺点,而Nacos则会在服务集群已经被改变了的时候,即使将更新信息主动推送给消费者,同时Nacos也支持消费者定时30秒主动拉取注册中心信息。
总结:
- Nacos与eureka的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
- Nacos与Eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式