§1 Distro 协议
§1.1 基本规则
- nacos 每个节点负责自己一部分的写请求
- 每个节点会把自己负载的数据同步给其他节点
- 每个节点定时发送自己负责数据的校验值到其他节点以保证一致性
- 每个节点独立处理读请求,实时从本地发回响应
- 新增 Distro 节点会进行全量数据拉取
轮询所有节点,点对点拉取数据
§1.2 关键类
DistroFilter
Distro 协议入口
DistroProtocol
Distro 协议具体实现
§1.3 校验
- 校验是通过定时任务实现的
DistroProtocol
构造器中调用了startDistroTask()
- 此方法中开启了两个任务
- 校验任务:
startVerifyTask()
- 数据加载任务:
startLoadTask()
- 校验任务:
- 核心代码如下
private void startVerifyTask(){
GlobalExecutor.schedulPartitionDataTimedSync(
new DistroVerifyTask(memberManager,distroComponentsHolder),
distroConfig.getVerifyIntervalMillis()
);
}
§2 注册中心
§2.1 注册中心工作流程
provider
- 启动时建立 grpc 连接到 nacos-server,注册服务
- 拉取 nacos-server 服务列表,选取第一个尝试建立连接
- 连接成功,使用此连接注册
- 连接失败,选取下一个尝试建立连接
- 每 5 秒空闲连接时,发送健康请求检查至 nacos-server
- 正常返回:更新时间
- 不正常返回:重连其他 nacos-server 节点
consumer
- 启动时从 nacos-server 拉取服务列表
- 开启长链接订阅 nacos-server 推送的数据
- 每隔 60s 从 nacos-server 拉取一次配置
nacos-server
- 记录服务注册的数据
- 定时心跳检查任务
§2.2 注册数据的持久化
服务注册信息的逻辑结构
即客户端拉取到的,服务端的服务注册数据结构
示意图
源码中的声明
//ServiceManager
//namespace -- group::serviceName -- Service
private final Map<String,Map<String,Service>> serviceMap = new ConcurrentHashMap();
//Service
//clusterName -- Cluster
private Map<String,Cluster> clusterMap = new HashMap<>();
//Cluster
private Set<Instance> persistentInstances = HashSet<>();//持久化
private Set<Instance> ephemeralInstances = HashSet<>();//临时化
客户端连接数据结构
即,服务端持有的,客户端的连接数据
示意图
源码中的声明
//ClientServiceIndexesManager
//服务 -- client id 的集合
private final ConcurrentMap<Service,Set<String>> publisherIndexes = new ConcurrentHashMap<>();
//AbstractClient
//服务 -- 服务实例发布信息
protected final ConcurrentHashMap<Service,InstancePublishInfo> publishers = new ConcurrentHashMap<>();