做者 | 杨翊(席翁) Nacos PMC
来源|阿里巴巴云原生公众号python
Nacos 在阿里巴巴起源于 2008 年五彩石项目,该项目完成了微服务拆分和业务中台建设,随着云计算和开源环境的兴起,2018 年咱们深入感觉到开源软件行业的影响,所以决定将 Nacos 开源,输出阿里十年关于服务发现和配管管理的沉淀,推进微服务行业发展,加速企业数字化转型。数据库
目前 Nacos 支持主流微服务开发语言 & 主流服务框架和配置管理框架,好比支持 Duboo 和 SCA, 还对接了一些云原生的组件好比 coreDNS 和 sentinel 等。缓存
客户端语言方面支持诸如 Java、go python 等主流语言,还有近期刚发布正式版本的 C# 和 C++,在此感谢全部社区贡献者的支持。网络
Nacos 开源 2 年多以来,共发布了 34 个版本,其中有一些比较重要的里程碑版本;Nacos 还很是年轻,有很大的进步空间,欢迎社区及各界大佬一块儿共同建设。数据结构
接下来咱们看一下 nacos1.x 架构及其分析一下存在的比较重要的问题。首先来看一下架构简图。架构
Nacos 1.X 大体分为 5 层, 分别是接入、通讯、功能、同步和持久化。负载均衡
接入层是用户最直接交互的层面,主要有 Nacos 客户端,以及依赖客户端的 Dubbo 和 SCA 以及用户操做的控制台 Console 组成。客户端和 Console 进行服务和配置操做,统一经过 HTTP 的 OpenAPI 发起通讯请求。框架
通讯层主要基于 HTTP 的短链接请求模型进行,部分推送功能经过 UDP 进行通讯。socket
功能目前有服务发现和配置管理,这层也就是实际管理服务和配置的业务层。分布式
同步层有数据同步的 AP 模式 Distro 和 CP 模式 Raft,还有有一个最简易的水平通知 Notify,用处各不相同:
持久化层 Nacos 使用 MySQL、Derby 和本地文件系统来进行数据的持久化 配置信息,用户信息,权限信息存储在 MySQL 或 Derby 数据库中, 持久化服务信息及服务和实例元数据信息存储在本地文件系统。
咱们经过一个服务发现的流程,再深刻熟悉一下 Nacos 1.X 架构和基于当前架构的 Nacos 服务发现模型。
Nacos 客户端注册服务会经过 OpenAPI 发送 Http 注册服务的请求,请求内容会带上服务信息及实例信息,一般这个步骤是由微服务框架 SCA 和 dubbo 完成。
服务端收到请求后,会先在 Contoller 中进行数据的读取和校验,好比 IP 是否合法,服务名是否正确等等。校验经过后,若是这个服务是第一次注册,Nacos 会在服务端生成一个 Service 对象,而后把此次注册的实例信息存入这个 Service 对象中;若是 Nacos 服务端已经有了这个 Service 对象,那么就会直接把新注册的实例信息存入对象。这个 Service 对象经过 命名空间+Group+Service 的组合来保证惟一性。
完成实例存入 Service 的同时,会触发两个事件,其中一个事件是用于数据同步的,Nacos 服务端会根据这个服务是不是临时对象的信息,使用 Distro 或者 Raft 协议进行同步,通知其余的 Nacos 节点该服务发生了变动;另外一个事件则通知在该 Nacos 服务节点上订阅了该服务的订阅者,并根据订阅者信息,经过 UDP 的方式,把最新的服务列表推送到订阅者客户端上。这就完成了一次服务注册流程。
另外,对于那些被定义为持久化的服务的全部信息,都会经过 raft 协议,保证可以写入到文件系统中被持久化。
最后,其余的 Nacos 节点,在经过同步而进行 Service 变动的时候也会触发通知订阅者的事件,从而使在其余 Nacos 服务节点上订阅该服务的订阅者也能收到推送。
粗略介绍了下 Nacos1.X 的架构和服务发现模型,接下来分析一下 Nacos1.X 架构所面临的几个比较重要的问题。
一句话总结,心跳多,无效查询多,心跳续约感知变化慢,链接消耗大,资源空耗严重。
经过心跳续约,当服务规模上升时,特别是相似 Dubbo 的接口级服务较多时,心跳及配置元数据的轮询数量众多,致使集群 TPS 很高,系统资源高度空耗。
心跳续约须要达到超时时间才会移除并通知订阅者,默认为 15s,时延较长,时效性差。若改短超时时间,当网络抖动时,会频繁触发变动推送,对客户端服务端都有更大损耗。
因为 UDP 不可靠,所以客户端测须要每隔一段时间进行对帐查询,保证客户端缓存的服务列表的状态正确,当订阅客户端规模上升时,集群 QPS 很高,但大多数服务列表其实不会频繁改变,形成无效查询,从而存在资源空耗。
HTTP 短链接模型,每次客户端请求都会建立和销毁 TCP 连接,TCP 协议销毁的连接状态是 WAIT_TIME,彻底释放还须要必定时间,当 TPS 和 QPS 较高时,服务端和客户端可能有大量的 WAIT_TIME 状态连接,从而会致使 connect time out 错误或者 Cannot assign requested address 的问题。
配置模块使用 HTTP 短链接阻塞模型来模拟长链接通讯,可是因为并不是真实的长链接模型,所以每 30 秒须要进行一次请求和数据的上下文切换,每一次切换都有引发形成一次内存浪费,从而致使服务端频繁 GC。
Nacos 2.X 在 1.X 的架构基础上 新增了对长链接模型的支持,同时保留对旧客户端和 openAPI 的核心功能支持。
通讯层目前经过 gRPC 和 Rsocket 实现了长链接 RPC 调用和推送能力。
在服务端测,新增一个连接层,用来将不一样类型的 Request 请求,未来自不一样客户端的不一样类型请求,转化为相同语意的功能数据结构,复用业务处理逻辑。同时,未来的流量控制和负载均衡等功能也会在连接层处理。
其余架构分层在大致上保持不变。
虽然 Nacos2.0 的在架构层次上并未作太大的变化,可是具体的模型细节却有不小的改动,依旧使用注册服务的流程,再深刻了解一下 Nacos2.0 服务模型的变化。
因为通讯使用了 RPC 方式,所以某一客户端的全部请求(不管是注册仍是订阅)都经过同一个连接和同一个服务节点进行,不像以前经过 HTTP 链接可能每次请求都请求在不一样的 Nacos 节点上,这就致使了服务发现的数据内容由原来的无状态化变为了与链接状态绑定的一种有状态数据。为了适应这种变化,须要改变一下数据模型,所以抽象了一个新数据结构,将同一个客户端经过该连接发布和订阅的内容关联起来,暂命名为 Client。这个 Client 不是客户端的意思,而是这个客户端所相关的数据内容,一个连接与一个 Client 对应。
当客户端发布了服务时,该客户端所发布的全部服务与订阅者信息会被更新到与该客户端连接相对应的 Client 对象中,而后经过事件机制触发对索引信息的更新。这个索引信息是客户端连接和服务的索引,方便快速聚合生成须要推送的服务纬度的数据。
索引信息更新完成后,会触发推送事件,此时会将全部和该服务有关的 Client 对象,经过刚产生的索引信息聚合起来,当数据聚合完成后,再从客户端连接中筛选出订阅该服务的订阅者的客户端连接,将推送数据经过该连接,推送回去。这样一次发布变动的主链路就完成了。
回过头看数据同步,客户端发布了服务时实际更新的对象从原来的 Service 变成 Client 对象,因此须要同步的内容也变成了 Client 对象;同时服务端间的通讯方式也会换成 RPC。这里只有真正被客户端更新的 Client 对象会触发同步,若是是经过同步而更新的 Client 对象不会再次触发同步。
最后看 Metadata,Metadata 是从 1.X 版本中的 Service 对象和 Instance 对象中分离出来的一些属性:好比服务的元数据 label 标签,实例的上下线状态、权重和元数据 label 标签等。这些元数据能够被 openAPI 单独修改,在聚合数据时生效。之因此将元数据拆分出来,区别于基础数据,缘由是基础数据好比:ip 端口,服务名等一经发布不该该被修改,并且应当以发布时的信息为准;但其余的原数据,好比上下线状态和权重,一般是在运行过程当中动态调节的,所以拆分开以后,分为两条不一样的处理工做流应该更加合理。
前面简要介绍了 Nacos 2.0 的架构和新模型的工做方式,接下来咱们分析一下这样的改动有哪些优缺点。
客户端再也不须要定时发送实例心跳,只须要有一个维持链接可用 keepalive 消息便可。重复 TPS 能够大幅下降。
TCP 链接断开能够被快速感知到,提高反应速度。
长链接的流式推送,比 UDP 更加可靠;nio 的机制具备更高的吞吐量,并且因为可靠推送,能够加长客户端用于对帐服务列表的时间,甚至删除相关的请求。重复的无效 QPS 能够大幅下降。
长链接避免频繁链接开销,能够大幅缓解 TIME_ WAIT 问题。
真实的长链接,解决配置模块 GC 问题。
没有银弹的方案,新架构也会引入一些新问题:
内部结构复杂度上升,管理链接状态,链接的负载均衡须要管理。
数据又原来的无状态,变为与链接绑定的有状态数据,流程链路更长。
接下来简单分享下 Nacos 2.X 的后期规划,主要分为文档、质量和 Roadmap。
在文档和质量方面,Nacos 1.X 都作的不是很好。文档内容较少,仅有简单使用文档;和版本有必定脱节,更新不及时;没有对技术内容的说明,参与贡献难度高。代码质量及测试质量也不是很高,虽然已经使用 checkstyle 进行了 codeStyle 的校验以及开启了社区协做 review。可是这还远远不够。Nacos 2.X 将会逐步更新、细化官网使用文档;经过电子书对技术细节进行解析;经过 Github 展现技术方案,促进讨论及贡献;而且对代码进行大量重构及 UT 和 IT 的治理工做,在将来将 Benchmark 也会开源出来,方便给开源用户进行压测。
而 RoadMap 方面,Nacos 2.X 会对项目作大幅度的重构,完成初步插件化,并对刚才 2.0 架构的一些缺点,如负载均衡,可观测性进行提高。
杨翊,花名席翁。Nacos PMC,主要参与的是服务发现模块,和作一些内核重构和提高的工做。Apache SharadingSphere PMC,主要负责和参与过的模块有 路由模块、分布式事务、 数据同步、以及弹性扩容。