架构设计之微服务注册中心选型

ZooKeeper、Consul、Eureka和新生的Nacos 都实现了注册中心的功能。那么从哪些方面进行对比,进而选型呢?程序员

 

 

1.数据模型:网络

注册中心的核心数据是服务的名字和它对应的网络地址,当服务注册了多个实例时,咱们须要对不健康的实例进行过滤或者针对实例的一些特征进行流量的分配,那么就须要在实例上存储一些例如健康状态、权重等属性。随着服务规模的扩大,渐渐的又须要在整个服务级别设定一些权限规则、以及对全部实例都生效的一些开关,因而在服务级别又会设立一些属性。再日后,咱们又发现单个服务的实例又会有划分为多个子集的需求,例如一个服务是多机房部署的,那么可能须要对每一个机房的实例作不一样的配置,这样又须要在服务和实例之间再设定一个数据级别。数据结构

 

2.数据一致性:架构

数据一致性是分布式系统永恒的话题,Paxos协议的艰深更让数据一致性成为程序员大牛们吹水的常见话题。不过从协议层面上看,一致性的选型已经很长时间没有新的成员加入了。目前来看基本能够归为两家:一种是基于Leader的非对等部署的单点写一致性,一种是对等部署的多写一致性。负载均衡

 

3.负载均衡:框架

负载均衡严格的来讲,并不算是传统注册中心的功能。通常来讲服务发现的完整流程应该是先从注册中心获取到服务的实例列表,而后再根据自身的需求,来选择其中的部分实例或者按照必定的流量分配机制来访问不一样的服务提供者,所以注册中心自己通常不限定服务消费者的访问策略。Eureka、Zookeeper包括Consul,自己都没有去实现可配置及可扩展的负载均衡机制,Eureka的负载均衡是由ribbon来完成的,而Consul则是由Fabio作负载均衡。运维

服务端的负载均衡,给服务提供者更强的流量控制权,可是没法知足不一样的消费者但愿使用不一样负载均衡策略的需求。而不一样负载均衡策略的场景,确实是存在的。而客户端的负载均衡则提供了这种灵活性,并对用户扩展提供更加友好的支持。可是客户端负载均衡策略若是配置不当,可能会致使服务提供者出现热点,或者压根就拿不到任何服务提供者。分布式

 

4.健康检查:性能

Zookeeper和Eureka都实现了一种TTL的机制,就是若是客户端在必定时间内没有向注册中心发送心跳,则会将这个客户端摘除。Eureka作的更好的一点在于它容许在注册服务的时候,自定义检查自身状态的健康检查方法。这在服务实例可以保持心跳上报的场景下,是一种比较好的体验,在Dubbo和SpringCloud这两大致系内,也被培养成用户心智上的默认行为。Nacos也支持这种TTL机制,不过这与ConfigServer在阿里巴巴内部的机制又有一些区别。Nacos目前支持临时实例使用心跳上报方式维持活性,发送心跳的周期默认是5秒,Nacos服务端会在15秒没收到心跳后将实例设置为不健康,在30秒没收到心跳时将这个临时实例摘除。插件

客户端健康检查和服务端健康检查有一些不一样的关注点。客户端健康检查主要关注客户端上报心跳的方式、服务端摘除不健康客户端的机制。而服务端健康检查,则关注探测客户端的方式、灵敏度及设置客户端健康状态的机制。从实现复杂性来讲,服务端探测确定是要更加复杂的,由于须要服务端根据注册服务配置的健康检查方式,去执行相应的接口,判断相应的返回结果,并作好重试机制和线程池的管理。这与客户端探测,只须要等待心跳,而后刷新TTL是不同的。同时服务端健康检查没法摘除不健康实例,这意味着只要注册过的服务实例,若是不调用接口主动注销,这些服务实例都须要去维持健康检查的探测任务,而客户端则能够随时摘除不健康实例,减轻服务端的压力。

 

5.性能与容量:

虽然大部分用户用到的性能不高,可是他们仍然但愿选用的产品的性能越高越好。影响读写性能的因素不少:一致性协议、机器的配置、集群的规模、存量数据的规模、数据结构及读写逻辑的设计等等。在服务发现的场景中,咱们认为读写性能都是很是关键的,可是并不是性能越高就越好,由于追求性能每每须要其余方面作出牺牲。Zookeeper在写性能上彷佛能达到上万的TPS,这得益于Zookeeper精巧的设计,不过这显然是由于有一系列的前提存在。首先Zookeeper的写逻辑就是进行K-V的写入,内部没有聚合;其次Zookeeper舍弃了服务发现的基本功能如健康检查、友好的查询接口,它在支持这些功能的时候,显然须要增长一些逻辑,甚至弃用现有的数据结构;最后,Paxos协议自己就限制了Zookeeper集群的规模,三、5个节点是不能应对大规模的服务订阅和查询的。

 

6.易用性:

易用性也是用户比较关注的一块内容。产品虽然能够在功能特性或者性能上作到很是先进,可是若是用户的使用成本极高,也会让用户望而却步。易用性包括多方面的工做,例如API和客户端的接入是否简单,文档是否齐全易懂,控制台界面是否完善等。对于开源产品来讲,还有一块是社区是否活跃。在比较Nacos、Eureka和Zookeeper在易用性上的表现时,咱们诚邀社区的用户进行全方位的反馈,由于毕竟在阿里巴巴集团内部,咱们对Eureka、Zookeeper的使用场景是有限的。从咱们使用的经验和调研来看,Zookeeper的易用性是比较差的,Zookeeper的客户端使用比较复杂,没有针对服务发现的模型设计以及相应的API封装,须要依赖方本身处理。对多语言的支持也不太好,同时没有比较好用的控制台进行运维管理。

 

7.集群扩展性:

集群扩展性的另外一个方面是多地域部署和容灾的支持。当讲究集群的高可用和稳定性以及网络上的跨地域延迟要求可以在每一个地域都部署集群的时候,咱们现有的方案有多机房容灾、异地多活、多数据中心等。

首先是双机房容灾,基于Leader写的协议不作改造是没法支持的,这意味着Zookeeper不能在没有人工干预的状况下作到双机房容灾。在单机房断网状况下,使机房内服务可用并不难,难的是如何在断网恢复后作数据聚合,Zookeeper的单点写模式就会有断网恢复后的数据对帐问题。Eureka的部署模式自然支持多机房容灾,由于Eureka采用的是纯临时实例的注册模式:不持久化、全部数据均可以经过客户端心跳上报进行补偿。上面说到,临时实例和持久化实例都有它的应用场景,为了可以兼容这两种场景,Nacos支持两种模式的部署,一种是和Eureka同样的AP协议的部署,这种模式只支持临时实例,能够完美替代当前的Zookeeper、Eureka,并支持机房容灾。另外一种是支持持久化实例的CP模式,这种状况下不支持双机房容灾。

 

8.用户扩展性:

在框架的设计中,扩展性是一个重要的设计原则。Spring、Dubbo、Ribbon等框架都在用户扩展性上作了比较好的设计。这些框架的扩展性每每由面向接口及动态类加载等技术,来运行用户扩展约定的接口,实现用户自定义的逻辑。在Server的设计中,用户扩展是比较审慎的。由于用户扩展代码的引入,可能会影响原有Server服务的可用性,同时若是出问题,排查的难度也是比较大的。设计良好的SPI是可能的,可是由此带来的稳定性和运维的风险是须要仔细考虑的。在开源软件中,每每经过直接贡献代码的方式来实现用户扩展,好的扩展会被不少人不停的更新和维护,这也是一种比较好的开发模式。Zookeeper和Eureka目前Server端都不支持用户扩展,一个支持用户扩展的服务发现产品是CoreDNS。CoreDNS总体架构就是经过插件来串联起来的,经过将插件代码以约定的方式放到CoreDNS工程下,从新构建就能够将插件添加到CoreDNS总体功能链路的一环中。

全部产品都应该尽可能支持用户运行时扩展,这须要Server端SPI机制设计的足够健壮和容错。Nacos在这方面已经开放了对第三方CMDB的扩展支持,后续很快会开放健康检查及负载均衡等核心功能的用户扩展。目的就是为了可以以一种解耦的方式支持用户各类各样的需求。

 

相关文章
相关标签/搜索