写点什么

Nacos 注册中心之概要设计

用户头像
捉虫大师
关注
发布于: 41 分钟前

前言

在之前的文章中分析了 Nacos 配置中心,配置中心的核心是配置的创建、读取、推送。


注册中心的核心比配置中心多一个服务探活模块,他俩的相似度非常高,甚至阿里内部的注册中心就叫ConfigServer


Nacos 注册中心打算分成几个模块来分析,本文重点在于概要设计,基于 2.0.0 版本。

环境搭建

用 Nacos 的源码来搭建源码阅读和调试环境,可参考《Nacos配置中心模块详解》 Nacos调试环境搭建部分。


其中 JVM 参数可以指定只启动 Naming 模块,也可以不指定,默认全都启动。


example 模块下将 NamingExample 复制一份进行测试。

设计概要

服务发现模型

客户端视角的服务发现模型(注意:服务端视角的模型定义与客户端视角有区别)包含以下几点内容:


  • Service:服务

  • Cluster:集群

  • Instance:实例


代码注释:We introduce a 'service --> cluster --> instance' model, in which service stores a list of clusters, which contains a list of instances


他们的关系如下


Service


  • name:服务名

  • protectThreshold:保护阈值,限制了实例被探活摘除的最大比例

  • appName:服务的应用名,暂无实际用处

  • groupName:分组名

  • metadata:元数据

Cluster


  • serviceName:所属服务名

  • name:集群名

  • healthChecker:服务探活配置,此处仅对服务端主动探活生效,有 TCP、HTTP、MySQL、None 几种方式,默认 TCP

  • defaultPort:默认端口

  • defaultCheckPort:默认探活端口

  • useIPPort4Check:是否使用 port 进行探活

  • metadata:元数据

Instance


  • instanceId:实例 id,唯一标志,Nacos 提供了simplesnowflake两种算法来生成,默认是simple,其生成方式为ip#port#clusterName#serviceName

  • ip:实例 ip

  • port:实例 port

  • weight:实例权重

  • healthy:实例健康状态

  • clusterName:所属集群名

  • serviceName:所属服务名

  • metadata:元数据

  • enabled:是否接收请求,可用于临时禁用或摘流等场景

  • ephemeral:是否为临时实例,后文会介绍该参数




  • getInstanceHeartBeatInterval:获取实例心跳上报间隔时间,默认 5 秒,可配置

  • getInstanceHeartBeatTimeOut:获取心跳超时时间,15 秒,配置

  • getIpDeleteTimeout:获取 ip 被删除的超时时间,默认 30 秒,可配置

  • getInstanceIdGenerator:获取 id 生成器


除了上述的三层模型外,Nacos 注册中心和配置中心有着一样的 namespace 设计,与 client 绑定,可隔离环境,租户。

接口设计

  • registerInstance:注册实例

  • deregisterInstance:注销实例

  • getAllInstances:获取一个服务的所有实例(包括不健康)

  • selectInstances:根据条件获取一个服务的实例

  • selectOneHealthyInstance:根据负载均衡策略获取服务的一个健康的实例

  • subscribe:订阅服务

  • unsubscribe:取消订阅服务

  • getServicesOfServer:根据条件分页获取所有服务

交互流程

Nacos 2.0 为 ephemeral 不同的实例提供了两套流程:


  • ephemeral=false,永久实例,与 server 端的交互采用 http 请求,server 节点间数据同步采用了 raft 协议,健康检查采用了 server 端主动探活的机制

  • ephemeral=true,临时实例,与 server 端的交互采用 grpc 请求,server 节点间数据同步采用了 distro 协议,健康检查采用了 TCP 连接的 KeepAlive 模式

临时实例的交互流程

  • client 初始化,与 server 建立连接

  • 只与其中一台 server 节点建立长连接

  • client 注册服务,将 serviceName+ip+port+clusterName 等数据打包发送 grpc 请求

  • 同时客户端缓存已注册过的服务,当 client 与 server 连接断开重连时,client 重新将这些数据注册到 server 端

  • server 端接收到 client 的注册请求,将注册信息存入 client 对象(用于保存 client 的所有数据)中,并触发 ClientChangedEvent、ClientRegisterServiceEvent、InstanceMetadataEvent

  • ClientChangedEvent 触发 server 节点之间的数据同步(distro 协议)

  • ClientRegisterServiceEvent 触发更新 publisherIndexes(保存 service => clientId 的 Map<Service, Set<String>>,即哪些客户端注册了这个服务的索引),同时也触发一个 ServiceChangedEvent,该事件负责向监听该服务的客户端进行推送

  • InstanceMetadataEvent,处理元数据,Nacos 在 2.0 中将元数据与基础数据拆分开,分为不同的处理流程

  • client 订阅服务

  • 根据 serviceName、groupName、clusters 信息生成 key,创建 eventListener,同时向 server 端发送订阅请求,并缓存订阅信息,用于连接断开重连后再次向 server 端发送信息

  • server 端接收到 client 的订阅请求

  • 将订阅信息打包为 subscribers,并存入 client 对象中,触发 ClientSubscribeServiceEvent 事件

  • ClientSubscribeServiceEvent 事件更新 subscriberIndexes(保存 service => clientId 的 Map<Service, Set<String>>,即哪些客户端订阅了这个服务的索引),同时触发 ServiceSubscribedEvent 事件

  • ServiceSubscribedEvent 事件会延时 500ms 向该 client 推送该服务的最新数据

  • 反向的操作如注销、取消订阅与正向操作类似,不再赘述

最后

本文从总体上分析了 Nacos 2.0 的模型设计、接口设计以及交互流程,读完后对 Nacos 的服务发现有一个整体上的认识。后续篇幅会从细节入手,如 dubbo Nacos 扩展、一致性协议、探活、CMDB 扩展等逐一进行分析。




关于作者:专注后端的中间件开发,公众号"捉虫大师"作者,关注我,给你最纯粹的技术干货



发布于: 41 分钟前阅读数: 3
用户头像

捉虫大师

关注

还未添加个人签名 2018.09.19 加入

欢迎关注我的公众号“捉虫大师”

评论

发布
暂无评论
Nacos注册中心之概要设计