nacos2.0架构设计与模型

nacos2.0架构设计与模型


一、Nacos 1.X架构及问题?

在这里插入图片描述

Nacos 1.X 大致分为5层, 分别是接入、通信、功能、同步和持久化。

接入层是用户最直接交互的层面,主要有Nacos客户端,以及依赖客户端的Dubbo和SCA以及用户操作的控制台Console组成。 客户端和Console进行服务和配置操作,统一通过HTTP的OpenAPI发起通信请求。

通信层主要基于HTTP的短连接请求模型进行,部分推送功能通过UDP进行通信。

功能目前有服务发现和配置管理,这层也就是实际管理服务和配置的业务层。

同步层有数据同步的AP模式Distro和CP模式Raft,还有有一个最简易的水平通知Notify,用处各不相同:

Distro:非持久化服务的同步模式
Raft:持久化服务的同步模式、以及使用Derby作为配置的存储时同步配置操作。
Notify:使用MySQL作为配置的存储时,通知其他节点更新缓存及发起配置推送。
持久化层Nacos使用MySQL、Derby和本地文件系统来进行数据的持久化 配置信息,用户信息,权限信息存储在MySQL或Derby数据库中, 持久化服务信息及服务和实例元数据信息存储在本地文件系统。

二、Nacos 1.X架构下的服务模型

## 1.引入库
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服务节点上订阅该服务的订阅者也能收到推送。

1.X架构存在的问题

在这里插入图片描述
1、 心跳数量多,导致TPS居高不下

通过心跳续约,当服务规模上升时,特别是类似Dubbo的接口级服务较多时,心跳及配置元数据的轮询数量众多,导致集群TPS很高,系统资源高度空耗。

2、 通过心跳续约感知服务变化,时延长

心跳续约需要达到超时时间才会移除并通知订阅者,默认为15s,时延较长,时效性差。若改短超时时间,当网络抖动时,会频繁触发变更推送,对客户端服务端都有更大损耗。

3、 UDP推送不可靠,导致QPS居高不下

由于UDP不可靠,因此客户端测需要每隔一段时间进行对账查询,保证客户端缓存的服务列表的状态正确,当订阅客户端规模上升时,集群QPS很高,但大多数服务列表其实不会频繁改变,造成无效查询,从而存在资源空耗。

4、基于HTTP短连接模型,TIME_WAIT状态连接过多

HTTP短连接模型,每次客户端请求都会创建和销毁TCP链接,TCP协议销毁的链接状态是WAIT_TIME,完全释放还需要一定时间,当TPS和QPS较高时,服务端和客户端可能有大量的WAIT_TIME状态链接,从而会导致connect time out错误或者Cannot assign requested address 的问题。

5、配置模块的30秒长轮询 引起的频繁GC

配置模块使用HTTP短连接阻塞模型来模拟长连接通信,但是由于并非真实的长连接模型,因此每30秒需要进行一次请求和数据的上下文切换,每一次切换都有引起造成一次内存浪费,从而导致服务端频繁GC。

三、Nacos 2.0架构及新模型

在这里插入图片描述
Nacos 2.X 在 1.X的架构基础上 新增了对长连接模型的支持,同时保留对旧客户端和openAPI的核心功能支持。
和Rsocket实现了长连接RPC调用和推送能力。

在服务端测,新增一个链接层,用来将不同类型的Request请求,将来自不同客户端的不同类型请求,转化为相同语意的功能数据结构,复用业务处理逻辑。同时,将来的流量控制和负载均衡等功能也会在链接层处理。

其他架构分层在大体上保持不变。

1.Nacos 2.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端口,服务名等一经发布不应该被修改,而且应当以发布时的信息为准;但其他的原数据,比如上下线状态和权重,通常是在运行过程中动态调节的,因此拆分开之后,分为两条不同的处理工作流应该更加合理。

2.Nacos 2.0架构的优缺点

在这里插入图片描述
优点
1、 客户端不再需要定时发送实例心跳,只需要有一个维持连接可用keepalive消息即可。重复TPS可以大幅降低。

2、 TCP连接断开可以被快速感知到,提升反应速度。

3、 长连接的流式推送,比UDP更加可靠;nio的机制具有更高的吞吐量,而且由于可靠推送,可以加长客户端用于对账服务列表的时间,甚至删除相关的请求。重复的无效QPS可以大幅降低。

4、 长连接避免频繁连接开销,可以大幅缓解TIME_ WAIT问题。

5、 真实的长连接,解决配置模块GC问题。

6、 更细粒度的同步内容,减少服务节点间的通信压力。

缺点
没有银弹的方案,新架构也会引入一些新问题

1、 内部结构复杂度上升,管理连接状态,连接的负载均衡需要管理。

2、 数据又原来的无状态,变为与连接绑定的有状态数据,流程链路更长。

3、 RPC协议的观测性不如HTTP。即使gRPC基于HTTP2.0Stream实现,仍然不如直接使用HTTP协议来的直观。

参考博客原址:https://my.oschina.net/u/3585447/blog/4818143

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值