注册中⼼的其他实现-Nacos
介绍
2018年6⽉,Eureka2.0宣布闭源(但是1.X版本仍然为活跃项⽬),同年7⽉份,阿⾥Nacos宣布开源.并快
速成为国内最受关注开源产品.作为Eureka的替代,Nacos已经成为了国内开发者的⾸选,⽬前NacosStar 已经突破28K(Eureka12K)
在最初开源时,Nacos选择进⾏内部三个产品合并统⼀开源(Configserver⾮持久注册中⼼,VIPServer持久化注册中⼼,Diamond配置中⼼).定位为:⼀个更易于构建云原⽣应⽤的动态服务发现,配置管理和服务管理平台.所以Nacos是⼀个注册中⼼组件,但它⼜不仅仅是注册中⼼组件.
截⾄⽬前,Nacos⼏乎⽀持了所有的主流语⾔,⽐如Java,Go,C++,Nodejs,Python,Scala等
Nacos安装
Eureka是jar包,Nacos是安装包的形式
下载链接
这两个随便下载一个就可以了
启动
我们要启动为单机模式,不然是会报错的,直接就闪退了
我们打开startup.cmd这个文件
这个修改为,26行左右
这样就修改为单机模式了
然后双击startup.cmd启动
这样就启动成功了
开始访问
端口号是8848
这样就是成功了
打开cmd
netstat -ano|findstr 8848
输入这个
第一个8076进程id就是我们查找的进程
taskkill /pid 8076 -f
这样就杀掉了进程了
点开conf文件夹
打开application.properties文件
这里就可以更改端口号了
我们改为10020
然后我们在双击启动
linux安装
cd /usr/local/src/
我们放在这个里面,这个是根目录下的
直接把刚刚的压缩包放在这个里面
然后就是直接解压
要先安装这个命令
apt-get install unzip
在解压
unzip nacos-server-2.2.3.zip
然后就还是要修改为单机模式启动
cd conf
vim application.properties
然后把端口号开放为10020
然后进入bin目录
cd bin
bash startup.sh -m standalone
standalone就是单机模式的意思
这样就启动了
直接输入ip/10020/nacos
网址
这样就成功了
最后就是访问
快速入门
以demo项目为基础,复制一个新的项目
先改父项目的artifactid
然后是子项目的pom里面的parent的artifactid
<properties>
<spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
这个加在父项目里面
然后就是在子项目里面引入nacos的依赖
两个子项目都要加这个nacos依赖
因为还要负载均衡,所以还要加上LoadBalance的依赖
两个子项目都要加入这个
然后就是修改配置了
要从哪个nacos获取呢–》我们使用Linux服务器上的nacos
这样就可以了
还要配置服务的名称
然后是修改product的
一个是注册到nacos一个是获取nacos,所以都要配置
配置都是一样的
下一步就是远程调用了
直接使用应用名称就可以了
然后是使用负载均衡
直接加上 @LoadBalanced就可以了
这样就OK了
然后是启动
注意nacos还要开放nacos端口号+1000和nacos端口号+1001的端口,不然我们的项目是无法启动的
就是开放11020的端口和11021端口
这样就成功了
然后就是启动多个order了,测试负载均衡
这样均衡的就都有了打印了
版本
这个就是SpringCloud阿里巴巴和SpringCloud和springboot的版本对应关系
服务下线
这里点击详情
右边有一个下线
这样我们多次访问,9091的日志就不会打印出来了
下线的时候这个机器就不会提供服务了
但是这个服务还是运行的状态
所以如果指定网址端口为9091去访问这个服务还是可以访问的
下线就是访问product-service这个应用的时候,不会去9091的端口号的
但是它本质是可以访问的
还可以上线的
权值配置
右边的编辑有一个权值的配置
就是分配流量的
这样这个9090的日志就很少了
但是直接这样配置并不会生效
因为我们的权值配置是属于nacos的
但是我们使用的loadbalancer有自己的负载均衡策略,所以并没有使用nacos的负载均衡
直接配置就可以开启nacos的负载均衡策略了
我们只需要订单服务的负载均衡策略就可以了
spring:
cloud:
loadbalancer:
nacos:
enabled: true
这样就可以了
负载均衡是配置在order的,因为它要负载去哪个product
所以我们请求几十次之后,这里的9090就只有几个到达了
常⻅问题
修改权重时,可能会报错:
报错信息:caused:errCode:500,errMsg:dometadataoperationfailed;caused:
com.alibaba.nacos.consistency.exception.ConsistencyException: The Raft Group
[naming_instance_metadata] did not find the Leader node;caused: The Raft Group
[naming_instance_metadata] did not find the Leader node;
原因:Nacos采⽤raft算法来计算Leader,并且会记录前⼀次启动的集群地址,当服务器IP改变时会导致raft记录的集群地址失效,导致选Leader出现问题.(⽹络环境发⽣变化时,IP地址也会发⽣变化)
解决办法:删除Nacos根⽬录下data⽂件夹下的protocol⽂件夹即可,然后重启nacos
同集群优先
我们就是希望order优先访问同一个机房的product
同机房优先访问就是同集群优先访问
访问不了再去访问其他集群
先给配置实例名称
就是给应用配置它所属于的集群名称
默认的集群名称是default
看这个我们给order配置集群名称为北京
这样集群就变成北京了
商品服务的集群也改成北京
我们只刷新9090
然后更改另外两个的集群为上海
右键编辑配置
-Dspring.cloud.nacos.discovery.cluster-name=ShangHai
增加一个这个配置就可以了
这样就成功了
现在我们希望ordeer访问的时候只去北京的product访问
明显是可以了
这个就是同集群优先访问
我们把北京的product下线
这样9091和9092就可以收到请求了
这个同集群优先访问也要开启nacos负载均衡策略
loadbalancer:
nacos:
enabled: true
就是开启这个
naocs健康检查
比如服务停掉了,nacos要有感知,要把它下线
Nacos中提供了两种健康检查机制:
客⼾端主动上报机制:
客⼾端通过⼼跳上报⽅式告知服务端(nacos注册中⼼)健康状态,默认⼼跳间隔5秒;
nacos会在超过15秒未收到⼼跳后将实例设置为不健康状态,超过30秒将实例删除
服务器端反向探测机制:
nacos主动探知客⼾端健康状态,默认间隔为20秒.
健康检查失败后实例会被标记为不健康,不会被⽴即删除
nacos注册中心是服务端,order和product是客户端
健康机制我们不能主动设置
健康机制是由nacos的服务实例类型相关的
nacos服务实例类型
Nacos的服务实例(注册的节点)分为临时实例和⾮临时实例.
临时实例:如果实例宕机超过⼀定时间,会从服务列表剔除,默认类型.
⾮临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例
Nacos对临时实例,采取的是客⼾端主动上报机制,对⾮临时实例,采取服务器端反向探测机制
我们前面的实例也就是结点,默认都是临时实例
我们停掉9091
然后9091直接就没了
如何配置永久实例呢
spring:
cloud:
nacos:
discovery:
ephemeral: false #
设置为⾮临时实例
我们把order设置为非临时实例,非临时实例是不会删除的
然后重启order
但是直接就失败了
这个是因为这个是一个临时实例,不能注册为永久实例
因为nacos会记录ip和端口号
会记录每一个实例的ip和端口号
之前是一个临时实例,并且被nacos记录了
那么就不能把临时实例改为非临时实例
也不能把非临时实例改为临时实例
本质原因是nacos记录了这个信息
那我们抹掉这个信息就可以了
我们需要删除nacos里面的data里面的prodocol里面的raft文件
ip端口号权重都是存在这个里面的
删掉文件之前,要先停掉这个服务
ps -ef | grep nacos
kill -9 pid
rm -rf raft
然后重启nacos
bash startup.sh -m standalone
然后再重启order
这样就变成了一个永久实例了
然后停掉order
然后健康状态变为了false
但是并不会删除掉这个实例
nacos环境隔离
创建环境就是namespace
选择这个命名空间
新建命名空间
我们的实例默认都在public这个环境里面
现在我们如何指定实例启动时候放在哪个环境里面呢
还是配置
我们这里去掉了永久实例,所以还要改一下nacos,都是一样的操作
配置一个namespace加上命令空间id就可以了
这样dev里面就有一个order了
这样访问就出错了
因为不同环境之间不能相互访问
所以dev环境里面没有product-service这个实例,所以就出错了
然后我们把product-service也放在dev环境下
我们重启9090
这样就成功了
nacos配置中心使用
除了注册中⼼和负载均衡之外,Nacos还是⼀个配置中⼼,具备配置管理的功能.
Namespace的常⽤场景之⼀是不同环境的配置区分隔离.例如开发测试环境和⽣产环境的配置隔离.
就是不同的环境有不同的配置,不同的配置之间有隔离
我们现在的配置都是写在文件中的,如果要更改配置,就是重启实例,很多的实例就要重启很多次
这个时候我们就可以用配置中心了
点开这个配置列表
注意就是服务管理的命名空间并不等同于配置管理的命名空间
服务管理的命名空间是通过配置文件中的这个namespace来配置的
如果要设置配置管理的命名空间就又要单独设置了,默认就是public
意思就是原来的配置文件配置的命名空间是服务管理的
点创建配置
Data ID就是写应用的名称
然后点击发布
然后在dev环境下再点创建配置
在哪个环境下点的创建配置,就是哪个环境的配置
然后我们就要在程序里面读取我们这个设置的配置了
要读取的话,还要设置相关的配置
引入nacos config依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud 2020.*之后版本需要引⼊bootstrap-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
然后就是修改配置文件了
微服务启动前,需要先获取nacos中配置,并与application.yml配置合并.在微服务运⾏之前,Nacos要求必须使⽤bootstrap.properties配置⽂件来配置NacosServer地址.
因为我们在nacos创建的配置就是product的,所以就给product配置bootstrap.properties就可以了
spring.application.name=product-service
spring.cloud.nacos.config.server-addr=ip:10020
配置两个,一个是应用名称,一个是nacos-config的地址
因为注册中心和配置中心可能是不同的服务,所以要说明一下配置中心的地址,还有要配置的应用名称
我们配置的应用名称和nacos中的data id是保持一致的
我们这里一个配置的是注册中心的地址
一个配置的是配置中心的地址
然后就是开始读取配置中心的配置了
单独搞一个控制类
然后启动product9090
注意我们的data id和我们的项目名称要一样
然后这里的应用名称要和data id一样
我们在启动9090
这样我们就拿到配置了
我们修改public下的配置的话,不用重启应用也是可以生效的
但是我们这里刷新并没有生效呢
如果要实时生效的话,还需要加上一个注解@RefreshScope
然后又重启
这样就可以实时生效了
配置中心详解
我们默认拿到的是public环境下的配置
如果要拿到dev环境上的,就要设置命令空间了
spring.cloud.nacos.config.namespace=51152a13-7911-49e3-bbdc-16fd5670a257
这个就是对命令空间的配置了
配置中心的namespace的配置肯定还是在bootstrap.yml中配置
命名空间可以在这两个地方复制
这样就变了
也是可以实时变化的
data id的配置
prefix就是spring:application:name: product-service配置的,就是应用名称是什么,不是data id的名称,我前面说错了,spring:application:name不和data id一样
spring.profiles.active就是配置配置中心的环境名称是什么
我们把这个spring.profiles.active改成dev
第三个file-exetension默认是properties,就不配置了
我们这样就配置好了data id
就可以找到data id了
所以我们看到配置一下data id
就监听了三个data id,就可以监听三个类型的data id
我们写上去的data id是product-service
所以监听到的是第三个
我们再来配置另外两个
我们看到这样的配置data id可以读取这三个data id
但是product-service-dev.properties的优先级是最高的
所以可以得出优先级了
没有设置命名空间,默认就是public的
总之应用名称和data id还是有点区别的
因为2022之后把bootstrap禁用了
所以要引入它的依赖
服务中心和配置中心的地址不一定一样
服务部署
部署在Linux上
最终程序运行的时候会先加载bootstrap.yml,在读取application.yml,然后把bootstrap.yml和application.yml两个配置合并起来,所有重复的配置可以删除
变
然后密码不同,要多个配置文件
然后在application.yml就是配置哪个文件生效,就是配置
profiles:
active:
我们在bootstrap.yml已经配置过了
所以可以直接删掉application.ym
然后就是
在product的pom里面
修改配置了,引入不同环境的变量
这个就是配置有什么环境
profiles:
active:就是配置用哪个环境的配置文件—》打包的时候勾选确定
但是bootstrap.yml不认识这个@@
运行直接就报错了
所以要支持@@的话,还要去加一些pom配置resources
resources这个就是指定maven打包的时候支持的静态文件是什么
directory是路径
我们先clean,打包,重启
注意要指定环境打包哦
这样就成功了
然后就是修改order的配置文件了
这个和之前的就没什么区别了
公共的配置可以写在application.yml里面,不是公共的就分开写
比如datasource
比如这样搞,打包选择不同环境的时候,都是会加载application.yml,其余两个就是选择的问题了
然后在application.yml设置哪个配置文件生效
但是运行却失败了
它说没有product-service这个实例
因为product-service的命名空间被我们删掉了,所有变成public的了
然后就可以部署了
prod打包
我们先要停掉之前的端口号
我们发现java进程只有这一个nacos
所以不用停了
mkdir logs
nohup java -jar order-service-1.0-SNAPSHOT.jar > logs/order.log &
nohup java -jar product-service-1.0-SNAPSHOT.jar > logs/product-9090.log &
nohup java -jar product-service-1.0-SNAPSHOT.jar --server.port=9091 > logs/product-9091.log &
nohup java -jar product-service-1.0-SNAPSHOT.jar --server.port=9092 > logs/product-9092.log &
然后就是测试一下了
但是我这个太卡了,就不给出截图了
我的服务器不行,只能运行两个,运行多个product就会很卡,但我们还是成功了
Nacos与Eureka的区别
共同点:
都⽀持服务注册和服务拉取
区别:
- 功能
Nacos除了服务发现和注册之外,还提供了配置中⼼,流量管理和DNS服务等功能. - CAP理论
Eureka遵循AP原则,Nacos可以切换AP和CP模式,默认AP.
Nacos根据配置识别CP或者AP模式.如果注册Nacos的Client的节点是临时节点,那么Nacos对这个Client节点的效果就是AP,反之是CP.AP和CP可以同时混合存在. - 服务发现
Eureka:基于拉模式.EurekaClient会定期从Server拉取服务信息,有缓存,默认每30秒拉取⼀次.
Nacos:基于推送模式.服务列表有变化时实时推送给订阅者,服务端和客⼾端保持⼼跳连接,就是product如果停掉的话,那么order那边是会打印相关的信息的,这就是实时推送,order就是订阅者,product就是服务
这里的点击之后一定要刷新,不然修改不会生效的
然后就是clean以前的