作者:heqingpan heqingpan@126.com
架构
r-nacos架构图
说明:
- r-nacos默认支持集群部署,单机就相当于一个节点的集群,后续有需要可以按需加入新的节点;
- 数据持久化使用raft协议分布式数据库(raft协议+节点文件存储),类似etcd;
- 只需对
RNACOS_CONFIG_DB_DIR:nacos_db
目录下的文件备份与恢复,即可实现数据的备份与恢复; - r-nacos控制台使用前后端分离架构;前端应用因依赖nodejs,所以单独放到另一个项目 r-nacos-console-web ,再通过cargo 把打包好的前端资源引入到本项目,避免开发rust时还要依赖nodejs。
多实例的raft和distro分布式协议说明待补充
配置中心
配置模型图
配置中心raft协议
raft协议的主要逻辑:
- 节点区分角色:leader(主节点),follower(从节点),candidate(选举节点);
- 稳定状态是一个主节点,多个从节点;
- 主节点负责写入,写入时需要先把写入日志同步到其它节点,超过半数节点写入日志成功后才能提交日志到状态机。
- 主节点需要定时发心跳到从节点,从节点如果超时未收到心跳,则会发起选举。选举时收到超过半数节点的同意,就可以切换成主节点。
具体协议可以参考 raft协议论文
r-nacos 接入 raft的主要逻辑:
- 基于 async-raft 库实现raft协议,主要实现网络层和存储层。在 r-nacos中存储层的状态机就是配置中心。
- 配置中心接入raft 协议的状态机,由 raft 状态机驱动更新配置中心的内容。
r-nacos一个三节点的配置中心请求处理示例:
写入:
- 客户端随机向一个节点发起一个更新配置请求
- 在请求入口层加一个raft路由判断,如果本节点是主节点则处理,否则路由到指定主节点处理
- 主节点写入请求到raft日志
- 将请求同步到其它从节点
- 如果超过半数节点写入日志成功(包含自身),则提交请求日志到状态机中,配置写入配置中心。(其它从节点的提交在下次日志同步或心跳时提交)
- 返回处理结果
请求:
- 客户端随机向一个节点发起一个查询配置请求
- 收到请求的节点和单机处理一样,直接查询本节点配置中心数据返回。
注册中心类distro协议
协议主要逻辑:
- 每个节点有全量的数据,都可提供注册信息查询服务。
- 注册中心每个节点平等,按hash划分每个节点负责的内容;节点对负责的服务可写,否则转发到对应负责的节点处理。
- 通过 grpc协议注册的服务,接收的节点直接处理。
- 一个节点更新服务实例信息后再同步给其它节点。
具体协议可以参考java nacos 的distro协议实现 。 r-nacos 和 java版主体逻辑相同,但实现的细节有些区别。
r-nacos一个三节点的注册中心请求处理示例:
http 写入:
- 客户端随机向一个节点发起一个注册服务实例请求
- 请求跳过服务路由判断,如果服务路由的节点是本节点则处理,否则路由到指定的其它节点处理
- 收到本节点负责的服务实例请求,把请求注册到注册中心中
- 返回处理结果
- 异步同步更新的数据到其它节点
grpc 写入(不路由,本节点直接处理):
- 客户端随机向一个节点发起grpc长链接
- 客户端发起一个注册服务实例请求
- 像单机一样,把请求注册到注册中心中
- 返回处理结果
- 异步同步更新的数据到其它节点
查询:
- 客户端随机向一个节点发起一个查询服务信息请求
- 收到请求的节点和单机处理一样,直接查询本节点注册中心数据返回。
为什么http的写入与grpc写入的路由逻辑不同?
因为grpc的心跳是按长链接来处理,一个客户端的链接段开,则这个链接的所用请求都失效。【高效】
然后http的实例注册是无状态的,只能通过定时器按注册时间更新实例的状态;同时注册中心中实例是按服务分类维护的。 所以http注册的实例需要按服务做路由,这样才能支持不同的节点负责不同范围的服务。【低效】
所以在注册中心使用grpc协议的性能会比http协议性能好很多。
待补充...