Nacos项目演进
自从Nacos1.X
版本突破10000 Star后,随着用户深入和大规模使用开始逐渐暴露Nacos1.X
的性能问题,借此Nacos
开启了2.0的发展阶段,全面升级了通信协议、服务一致性模型、支持服务网格生态和多语言生态。
从HTTP短连接重构升级为长连接
Nacos1.x
版本主要基于HTTP
短连接构建服务注册与发现、配置管理系统。随着用户的服务量级的增大,HTTP
短连接架构暴露了一些问题。为了克服短连接的固有的技术瓶颈,Nacos
社区针对HTTP
短连接架构进行了一次基于长连接的重构升级,配置中心的推送功能通过长轮询构建,周期性地由客户端主动发送HTTP
请求并在发生更新时返回变更内容;而服务注册中心的推送则通过UDP
推送+HTTP
定期对账来实现。 然而,配置中心的长轮训、服务注册中心的定期对账,都需要周期性地对于服务端进行一次主动建连和配置传送,增大服务端的内存开销;随着Nacos
用户的服务数和配置数规模的增大,服务端的内存泄漏风险也大大增加。 为了更好的支撑用户的性能要求,克服HTTP
短连接架构固有的性能瓶颈,Nacos
社区在阿里巴巴集团内部充分验证的基础上,进行了一次基于长连接的重构升级。长连接时代的Nacos2.x
在原本1.x的架构基础上新增了对gRPC
长连接模型的支持,提高了整体的性能。
通信层目前通过gRPC实现了长连接RPC调用和推送能力
。升级完成之后,服务变化、配置变更等信息会通过gRPC
的双向流主动推送给客户端,而客户端只需要针对各个长连接主动发送轻量级的心跳即可。升级后的技术架构极大地减少了服务端处理数据的开销;同时,由于长连接基于可复用TCP
的机制,也大大降低了网络堵塞的风险。
压测验证:升级长连接之后,我们对Nacos2.0
进行了大量压测。压测结果显示,Nacos2.0
能够在10W
级规模下,稳定运行;相比Nacos1.X
版本的1.2W
规模,提升约10倍。
动态监听值Pull Or Push
当Nacos Config Server
上配置发生变化时,需要让相关Client
客户端应用程序感知配置的变化进而感知应用的变化,那么Nacos
客户端是如何实现配置变更的实时更新的呢?
一般来说:客户端和服务端之间的数据交互无非两种方式:Pull(拉)
和Push(推)
。
Pull
表示客户端从服务端主动拉取数据。Push
表示服务端主动把数据推送到客户端。
对于Push
模式来说,服务端需要维持和客户端的长连接,如果客户端的数量比较多,那么服务端需要耗费大量的内存资源来保存每个连接,并且为了检测连接的有效性,还需要心跳机制来维持每个连接的状态。
在Pull
模式下,客户端需要定时从服务端拉取一次数据,由于定时任务会存在一定的时间间隔,所以不能保证数据的实时性,并且在服务端配置长时间不更新的情况下,客户端的定时任务会做一些无效的Pull
。
Nacos
采用的是Pull(拉)
模式,并不是简单的Pull
,而是一种长轮训,它结合Push
和Pull
两者的优势,客户端采用长轮训的方式定时发起Pull
请求,去检查服务端配置信息是否发生了变更,如果发生了变更,则客户端会根据变更的数据获取最新的配置,所谓的长轮训,是客户端发起轮训请求之后,服务端如果有配置发生变更,就直接返回,如下如图所示:
Nacos整体的配置更新流程
- Nacos
采用的是一个长轮训的方式向Nacos Server
端发起配置更新查询的方式功能;
- 客户发起一次轮训请求到服务器端,当服务器端的配置没有发生任何变更的时候,这个连接会一直处于打开状态;
- 直到服务器端发生配置变更或者连接超时的时返回;
Nacos
获取服务端的配置变更的前提需要一个配置的比较,那客户端本地的配置信息与服务器端的配置进行比较,一旦发现与服务端的配置有差异,证明服务器端的配置发生了更新,这时候需要把更新的配置拉取到本地;Nacos
采用分片的方式对配置文件进行比较,防止配置文件比较多,比较的时间较长,对整体性能造成影响;- 采用长轮训的方式减少了
pull
的轮训的次数,利用长轮训的方式实现配置的动态更新功能。