欢迎来到 Nacos 的世界!
注意:博主当前使用的最新版2.2.2,随着时间变化博主使用的版本会落后
一.Nacos简介
1.Nacos(Dynamic Naming and Configuration Service):是个易于构建云原生应用的动态服务发现、配置管理和服务管理平台
2.Nacos 致力于发现、配置和管理微服务,快速实现动态服务发现、服务配置、服务元数据及流量管理
3.服务(Service)是 Nacos 世界的一等公民,支持几乎所有主流类型“服务”的发现、配置和管理、其中包括:
- Kubernetes Service
- gRPC Service
- Dubbo RPC Service
- Spring Cloud RESTful Service
4.Github项目: https://github.com/alibaba/nacos
5.官方站点:https://nacos.io/zh-cn/
二.Nacos 的关键特性
1.服务发现和服务健康监测:nacos作为服务注册中心可用于服务发现,并支持传输层(TCP)和应用层(HTTP)的健康检查,并提供了agent上报和nacos server端主动探测两种模式,另外还有统一的Dash Board。
2.动态配置中心:nacos可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置,消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷
3.动态 DNS 服务:nacos支持内网的简单DNS解析服务,以及以 DNS 协议为基础的服务发现
4.服务及其元数据管理:nacos能管理数据中心的所有服务及元数据,包括:服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务SLA 以及 metrics 统计数据
三.nacos相关图
1.架构图
2.数据模型
Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。
2.1名词解释
Namespace:命名空间,公共的命名空间师public
Group:分组,默认分组是DEFAULT_GROUP
Service:服务名称
DataId:配置文件名称
四.Nacos的安装
1.下载地址:https://github.com/alibaba/nacos/releases/tag/2.2.2
2.上传到自己的服务器中需要开放如下端口:8848,9848,9849
3.解压:tar zxvf nacos-server-2.2.2.tar.gz
4.在mysql中创建一个名为nacos的库,并且将nacos提供的sql进行执行
sql执行后应该有如下表
5.配置mysql的信息,配置文件信息在conf目录下的application.properties中
6.在application.properties开启授权
7.设置密钥为:SecretKey012345678901234567890123456789012345678901234567890123456789
8.设置请求名称
9.设置好后进行保存
10.进入nacos/bin目录进行启动
nacos默认为集群启动,所我在启动时需要加参数
启动命令:sh startup.sh -m standalone
如果想用sh startup.sh直接启动单机版,将cluster改为standalone后即可
11访问页面:
地址为:服务器ip:8848/nacos
用户名:nacos
密码:nacos
五.使用Nacos完成服务注册与发现
1.参考官方文档:https://nacos.io/zh-cn/docs/v2/ecology/use-nacos-with-spring-cloud.html
2.版本说明文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
3.博主采用的版本为下图红色标出
springboot2.6.13这个版本中nacos注册不上去,博主还在研究源码ing
4.创建工程Andy-parent, Andy-api,Andy-driver,Andy-order
Andy-parent:为父工程
Andy-api:为公公共模块
Andy-driver:司机模块
Andy-order:订单模块
5.在Andy-paren工程添加如下坐标
<!--SpringBoot版本-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.11</version>
</parent>
<properties>
<spring.cloud.version>2021.0.4</spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
</dependencies>
</dependencyManagement>
6.在Andy-api工程添加如下坐标
<!--web包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--bootstrap-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
7.在Andy-driver,Andy-order分别创建bootstrap.yml文件,并且添加如下配置
- Andy-driver
server:
port: 18081 # tomcat端口
spring:
application:
name: Andy-driver #服务名称
cloud:
bootstrap:
enabled: true #开启bootstrap加载
nacos:
discovery:
server-addr: 192.168.44.128:8848 #nacos地址
namespace: e466f8d6-6abd-4037-b3c4-add3ec61d003 #nacos命名空间
username: nacos #nacos用户名
password: nacos #nacos密码
- Andy-order
server:
port: 18082 # tomcat端口
spring:
application:
name: Andy-order #服务名称
cloud:
bootstrap:
enabled: true #开启bootstrap加载
nacos:
discovery:
server-addr: 192.168.44.128:8848 #nacos地址
namespace: e466f8d6-6abd-4037-b3c4-add3ec61d003 #nacos命名空间
username: nacos #nacos密码
password: nacos #nacos密码
7.在Andy-driver工程,Andy-order工程的启动类上加上@EnableDiscoveryClient注解
8.启动后我们可以看见nacos中有如下两个服务
六.使用Nacos作为配置中心
1.在Andy-api模块中添加如下坐标
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.分别在Andy-driver工程下的bootstrap.yml文件添加如下配置
spring:
cloud:
nacos:
config:
server-addr: 192.168.44.128:8848 #nacos地址
namespace: e466f8d6-6abd-4037-b3c4-add3ec61d003 #nacos命名空间
username: nacos #nacos密码
password: nacos #nacos密码
3.在nacos中创建配置
dataId组成部分为:${prefix}-${spring.profiles.active}.${file-extension}
假设添加一个一个数据库连接的配置
4.启动项目,不报错就表示成功
5.多环境配置
- 配置文件的克隆 (这里克隆一个Andy-driver-dev.yml)
- 在Andy-driver工程中的bootstrap.yml文件中添加以下配置
spring:
profiles:
active: dev
6.启动项目,没报错就成功了
七.Nacos配置项热更新
1.外部配置中心配置项发生变化时,应用端在无需重启应用的情况下能自动同步最新配置数据。
2.Environment 热更新
- Environment代表了应用的运行时环境,其中包括了profiles 和 properties,而properties属性可能来源于properties文件、JVM properties、system环境变量等等
- nacos配置变更后,environment对象中能自动同步变更的数据,可通过其String getProperty(String key);获取
3.@ConfigurationProperties 热更新
- ConfigurationProperties注解的作用是用于获取配置文件中的配置项并绑定到bean的属性上
- nacos配置变更后,ConfigurationProperties所标注bean的属性能自动刷新值
4.@Value + @RefreshScope热更新 - Value注解也是可以将指定的配置项绑定到bean的属性上
- nacos配置变更后,Value标注的属性默认不会自动刷新值,需要在对应bean上标注RefreshScope注解才可以
八.Nacos配置灰度发布
- 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/Btesting,即让一部分用户继续用产品特性A,一部分用户开始用产品新特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,直到把所有用户都迁移到B上面来。
- 灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,控制其影响范围
九.Nacos集群环境部署
1.找到nacos配置文件
2.将cluster.conf.example名称改为cluster.conf
3.修改配置为主机ip+端口号
4.将修改的文件保存,并且将整个nacos同步到集群主机上
5.进入nacao/bin 用sh startup.sh命令启动
6.访问主机,如果没有报错就成功了
十.Nacos服务-领域模型-健康机制
1.在NacosServer中,服务和配置是一等公民,而在Server侧服务信息的存储采用的是分级存储模型
- 服务:一组功能集的抽象
- 实例:服务在具体IP,端口上的提供者应用启动时的注册就是注册某个服务的实例
- 集群:服务之下,实例之上的中间层,便于统一管理实例集(默认是DEFAULT)
2.Nacos中的临时实例和持久实例 - 临时实例:nacosserver在该实例健康检查失败一定时间后会主动摘除它,且实例数据不持久化
- 持久实例:实例数据持久化,nacosserver在该实例健康检查失败后并不摘除该实例,除非客户端主动销毁
1.nacos默认的实例类型是临时实例,可以更改
2.临时实例的应用场景大多都是上层的服务,比如:SpringCloud服务,dubbo服务等
3.持久实例的应用场景是⼀些基础的组件,例如:数据库,缓存等【想以服务的形式对外提供】
4.临时实例和持久实例在健康检查上的方式不一样:临时实例使用客户端上报模式【心跳】,持久化实例使用服务端反向探测模式
3.Nacos中的健康检测
- Nacos中的健康检测
- TCP端口探测
- HTTP接口返回码探测需要在实例侧提供探测url
- MYSQL协议探测
- Nacos集群模式下的健康检测
4.Nacos健康检查机制总结
- Nacos服务的分级存储模型是:服务->集群->实例
- Nacos实例类型有什么
- 临时实例:数据不持久化,健康检查失败后服务端主动摘除实例,采用客户端主动上报心跳的方式进行健康检查
- 持久实例:数据持久化,健康检查失败后服务端不摘除实例,采用的是服务端主动探测的方式进行健康检查
- Nacos的健康检查机制
- 临时实例:客户端5s一次上报心跳,服务端15s收不到心跳标记实例不健康,30s收不到心跳则摘除实例
- 持久实例:服务端可以通过TCP端口探测,HTTP接口返回码探测,
MYSQL探测三种方式进行
十一.Nacos集群一致性协议
1.Nacos是⼀个需要存储数据的⼀个组件,故在集群模式下,就需要考虑如何保障各个节点之间的数据⼀致性以及数据同步,那就不得不引入共识算法来保障各个节点之间的数据的⼀致性
2.Nacos使用了哪种类型的一致性协议?
- Nacos是⼀个集服务注册发现以及配置管理于⼀体的组件,在集群中同时运行CP协议以及AP协议,
- 服务注册发现:服务之间感知对方必须依赖注册中心,因此对服务注册发现中心组件的可用性,提出了很高的要求,需要在任何场景下,尽最大可能保证服务注册发现能力可以对外提供服务
- 服务注册发现:服务之间感知对方必须依赖注册中心,因此对服务注册发现中心组件的可用性,提出了很高的要求,需要在任何场景下,尽最大可能保证服务注册发现能力可以对外提供服务
- 持久实例:一旦创建成功,在客户端不主动删除的情况下数据一直在,因此在创建的时候就要确保大部分的节点都保存了实例信息才算成功,故需要强⼀致性共识算法来保障数据的⼀致性-CP
- 配置管理:配置数据,是直接在Nacos服务端进行创建并进行管理的,必须保证大部分的节点都保存了此配置数据才能认为配置被成功保存了,否则就会丢失配置的变更,因此对于配置数据的管理,是必须要求集群中大部分的节点是强⼀致的-CP
3.Nacos选择了什么协议?
- 对于强一致性共识算法最多使用的就是Raft协议,并且有很多成熟的工业算法实现,比如蚂蚁金服的JRaft、Zookeeper的ZAB、Consul的Raft、百度的braft、ApacheRatis;
- Nacos是Java技术栈,因此只能在JRaft、ZAB、Apache Ratis中选择,但是ZAB因为和Zookeeper强绑定,再加上希望可以和Raft算法库的支持团队随时沟通交流,因此选择了JRaft
- 最终⼀致性协议有很多,比如Gossip、Eureka内的数据同步算法
- Nacos选择了阿里巴巴自研的Distro协议,Distro算法是集Gossip以及Eureka协议的优点并加以优化而出来的
4.Distro协议的主要设计思想
- Nacos每个节点是平等的都可以处理写请求,同时把新数据同步到其他节点
- 每个节点定时发送自己负责数据的校验值到其他节点来保持数据⼀致性
- 每个节点独立处理读请求,及时从本地发出响应
5.几个场景进行Distro协议工作原理的介绍
-
数据初始化:新加入的Distro节点会进行全量数据拉取。具体操作是轮询所有的Distro节点,通过向其他的机器发送请求拉取全量数据
-
数据校验
- 在Distro集群启动之后,各台机器之间会定期的发送心跳
- 心跳信息主要为各个机器上的所有数据的元信息【校验值】
- ⼀旦在数据校验过程中,某台机器发现其他机器上的数据与本地数据不⼀致,则会发起⼀次全量拉取请求,将数据补齐
-
写操作
- 前置的Filter拦截请求,并根据请求中包含的IP和port等信息计算其所属的Distro责任节点,并将该请求转发到所属的Distro责任节点上
- 责任节点上的Controller将写请求进行解析,并完成写操作
- Distro协议定期执行Sync任务,将本机所负责的所有的实例信息同步到其他节点上
-
读操作:每台机器上都存放了全量数据,因此在每⼀次读操作中,Distro机器会直接从本地拉取数据。快速响应
-
Distro协议总结
- Distro协议的设计思想下,每个Distro节点都可以接收到读写请求,其数据存储在缓存中,并且会在启动时进行全量数据同步,并定期进行数据校验
- 所有的Distro协议的读写场景主要分为三种情况:
- 当该节点接收到属于该节点负责的实例的写请求时,直接写入
- 当该节点接收到不属于该节点负责的实例的写请求时,将在集群内部路由,转发给对应的节点完成写请求当该节点接收到
- 任何读请求时,都直接在本机查询并返回(因为所有实例都被同步到了每台机器上)