文章目录
- 1.简介
- 2.整体架构和原理
- 2.1 服务发现注册原理
- 2.1.1 注册和拉取数据
- 2.1.2 Server集群一致性
- 2.1.3 健康检查
- 2.2 配置中心原理
- 2.2.1 支持功能和资源模型
- 2.2.2 server集群数据一致性问题
- 2.2.3 client和server的通信监听改动方式
- 2.2.4 client拉取数据
- 2.2.5 client请求server的负载均衡问题
1.简介
Nacos由阿里在2018年开源出来的动态服务发现与配置管理服务,核心功能为动态服务发现和配置管理,具有四个优势:
- 易用:自带控制台和restfulAPI;
- 稳定:支撑了阿里双十一流量的大规模场景;
- 实时:数据变更毫秒级推送;
- 规模:具备强大的扩展性。
Nacos支持目前主流的Spring生态全栈,包括传统Spring、Springboot和Springcloud。
2.整体架构和原理
Nacos总体架构分为四个部分层:
- 用户层:与开发者或用户打交道的,包括控制台、restfulAPI和SDK等;
- 业务层:包含服务发现与注册管理,配置管理和元数据CURD能力;
- 内核层:分为一些基础功能,如日志、回调、推送和一致性协议等;
- 插件:如Metrics数据统计等功能插件。
由于Nacos框架整合了服务发现注册和配置中心两种功能,一般都会觉得既然一个框架实现了两种功能,这两种功能的实现肯定是大差不差的,或者有共同的代码实现逻辑的。但实际上Nacos的服务发现注册和配置中心的实现差异很大,因此从两种不同的功能原理上来分别阐述。
2.1 服务发现注册原理
服务发现注册框架一般而言需要满足以下功能:
- 支持服务提供者注册自身信息;
- 支持服务消费者拉取服务提供者的信息;
- 支持在Server集群内同步消费者和提供者的注册信息;
- 支持探测服务提供者和消费者是否存活。
Nacos1.0 server之间、server和client之间的通信方式为HTTP,Nacos2.0后改为了长连接。
2.1.1 注册和拉取数据
Nacos注册和拉取数据都是直接调用Server端HTTP接口,服务提供者在注册到Nacos Server端时可用ephemeral参数控制是否为临时节点,默认为临时节点。消费者拉取数据时可以选择是否订阅该数据,如果订阅了当订阅关系发生了改变时将会通知消费者,消费者的监听器会保存在本地内存。
2.1.2 Server集群一致性
Nacos发现注册功能通常会和Zookeeper和Eureka两者作比较,Zookeeper是CP,Eureka是AP,Nacos则同时支持CP和AP。
Nacos Server集群的一致性实现有两种方式:自研的AP一致性协议Distro,CP一致性协议Raft。Nacos集群支持同时运行两种协议,具体协议实现方式由客户端控制。当客户端的ephemeral参数为true,即临时节点,则会使用Distro;为false,即永久性节点,使用Raft协议。
Distro协议设计思想:
- Nacos每个节点都含有全量数据,平等的处理写请求,同时把新数据同步给其它节点;
- 每个节点只负责处理部分数据,定时发送自己负责数据的校验值给其它节点来保持数据一致性;
- 每个节点独立处理读请求,并本地响应。
原理:
- 启动时:刚启动或新加入的节点会轮询所有的Distro节点,通过向其它机器发送请求拉取全量数据,此时新加入的节点就会维护当前所有注册上来的临时性节点数据;
- 运行时:每台机器会定期发送元数据进行心跳检测,一旦发现数据不一致,则会发起一次全量同步,补齐数据;
- 执行写请求:客户端向server发送写请求时,会先经过Filter拦截转发到请求所属的Distro责任节点,责任节点再对写请求进行解析处理,最后经过定时任务执行Sync任务,把实力信息同步给其它节点。
这里需要注意,Distro的每个节点都有全量数据,但为了保证每台机器的性能,每台机器只会处理部分写请求,如果写请求直接到负责的机器上,则直接处理,没有则进行路由转发。如果客户端配置了多个Server的地址,客户端会随机选择一个发送请求,如果只配了一个,则只会往该Server发送请求。
Raft协议和Zookeeper的ZAB协议类似,差异点如下表格:
功能项 | ZAB | Raft |
---|---|---|
选举方式 | 投票过半主从选举 | 投票过半主从选举 |
选举规则 | 1. 日志id zxid是最大的;2. 选举迭代epoch谁大谁优先;3. 自身机器配置id | 1. Leader的日志是最多的;2. 选举迭代term谁大谁优先;3. 内置超时等待时间,150-300ms随机,先超时则先发起投票,相当于随机初始优先级 |
角色差异 | 选举后有Leader、Follower和Observer;Leader和Follower由participant转换而来 | Leader和Follower统一由Candidate转换而来 |
日志同步 | 二阶段提交 | 二阶段提交 |
健康探测 | 由Leader发送ping,其它机器回应pong消息,需过半机器回应 | 由Leader发送心跳检测,需过半机器回应 |
2.1.3 健康检查
Nacos的Server间和Server-Client间都存在健康检查机制来探测是否存活,Server间通过定期发送sync命令进行心跳检测和数据同步。Server-Client间的健康检查则分两种模式:
- 临时节点:临时节点客户端在注册时实例时会生成一个定时任务,定时的随机向集群的一个Server发送心跳请求,Server集群便会更新同步该Client的心跳时间,当剔除后同步集群的注册信息;
- 永久节点:永久节点的心跳检测将会由Server端发起,当某个永久集群被Server机器负责时,该Server机器将会负责主动向永久节点发送心跳检测,当剔除后同步集群的注册信息。
2.2 配置中心原理
Nacos配置中心与市场中主流配置中心框架原理都大差不差,由控制台发布/更新/查询配置,Server集群负责更新配置库内容,并向Client提供监听功能,Client连接到Server,查询监听部分配置,当Server端发生改变时通知到对应的Client。
其区别在于每个步骤的具体实现方式,如:
- Server控制台支持的功能及数据资源模型;
- Server集群间的数据一致性问题;
- Client和Server的通信方式
- Client向Server端拉取数据和监听数据回调的方式;
- Client端请求Server的负载均衡问题。
每个配置中心的核心原理差异便是这五个,接下来我们就这五个问题深入Nacos的配置中心原理。
2.2.1 支持功能和资源模型
Nacos配置中心控制台支持的功能:
- 基于文件的配置方式:文件格式支持yml、properties和json等主要方式;
- 支持保存和修改数据是进行差异对比;
- 支持IP级别的灰度发布;
- 支持查看配置的历史改动情况,可对某次修改进行回滚;
- 支持查询不同client的监听情况。
Nacos资源模型:
- namespace:用于进行粗粒度的配置隔离,不同命名空间下可存在相同的group或dataId配置,默认使用public;
- group:区分配置的维度之一,默认命名采用DEFAULT_GROUP;
- dataId:某个配置集的ID,通常用于划分系统的配置集。
2.2.2 server集群数据一致性问题
Nacos配置中心多集群的架构模式如下图:
用户在Nacos的控制台修改完数据后,将会由VIP系统分发到各个Server系统,Server系统接收到后将请求结果入库,随后异步向其它的Server发送数据修改通知,其它的Server接收到通知后将会读取数据库全量数据缓存到本地,以便后续更快的响应数据。
因此Nacos1.0配置中心的server使用HTTP通知的方式来完成Server间的一致性,Nacos2.0改为了使用长连接进行通知。
server的发现有两种方式:地址寻址和服务器寻址。
- 地址寻址:在每台Nacos Server上都配置其它server的地址,需要人工维护每台Nacos的地址信息;
- 服务器寻址:所有的Nacos Server从一台服务器上拉取配置信息,官方推荐使用这种方式,如把地址信息统一配置在管理系统中提供接口查询。
因此Nacos官方称这种模式保证了可用性,但非一致性,因此属于AP。
2.2.3 client和server的通信监听改动方式
client和server的通信方式在1.0是长轮询,client端原理:client向server发送HTTP请求,超时时间为30s,在30s内如果收到了回复则说明有数据变更,接收返回信息并更新本地缓存数据,完成后再次发起长轮询;如果本次长轮询没有数据,则下次继续发起长轮询。
server端的处理原理:当接收到client的长轮询后,将会把其添加到订阅者数组中,当期间没发生数据变化时则在29.5s时回复给client空信息,以避免client网络超时抛异常;如果期间数据发生了改动,则会收到LocalDataChange事件,并匹配监听改动的订阅者,回复其改动信息,并将订阅者从列表中删除。
在Nacos2.0版本将长轮询改为了长连接。
2.2.4 client拉取数据
client在启动后将会调用server端的HTTP接口直接拉取数据,拉取下来的数据会在本地生成配置的快照,当客户端无法连接到Server时,可以使用本地的配置提高整体容灾能力,本地缓存不会过期。
2.2.5 client请求server的负载均衡问题
如果Nacos有多台Server且client配置了多个server地址,第一次调用时会随机获取一个server地址,如果后续网络和服务一直是正常的,则一直保持不变。但如果因为宕机或因网络问题连接不上时,则会获取下一个随机地址。