在实际的项目选型中,该如何考虑选择合适的注册中心呢?
我在网上找了很多资料,但都基本不是最新的,比如说几乎所有的资料都还在说只有Eureka支持Spring Cloud的集成,其他注册中心均不支持Spring Cloud。因此,就想要自己写一篇最新最全的注册中心的特点比较的文章,来帮助自己以及亲爱的粉丝们重新梳理他们的特点,以保证以更全方位的考虑来进行项目选型
| 序号 | 比较项 | Eureka | zookeeper | Nacos | Consul |
| 1 | 集群结构 | 平级 | 主从 | 支持平级和主从 | 主从 |
| 2 | 集群角色 | 主人 | Leader、follower observer | leader、follower、candidate | server-leader、server以及client |
| 3 | 是否可以及时知道服务状态变化 | 不能及时知道 | 会及时知道 | 不能及时知道 | 不能及时知道 |
| 4 | 一致性协议(CAP) | 注重可用性(AP) | 注重一致性(CP) | 支持CP和AP-如何实现 | 注重一致性(CP) |
| 5 | 雪崩保护 | 有 | 没有 | 有 | 没有 |
| 6 | 社区是否活跃 | Eureka2.0不再维护了 | 持续维护 | 持续维护 | 持续维护 |
| 7 | 管理端 | 有现成的eureka管理端 | 没有现成的管理端 | 有现成的管理端 | 有现成的管理端 |
| 8 | 负载均衡策略 | 使用ribbon实现 | 一般可以直接采用RPC的负载均衡 | 权重/metadata/Selector | Fabio |
| 9 | 权限控制 | 无 | 使用ACL实现节点权限控制 | RBAC-用户、角色、权限 | ACL |
| 10 | Spring Cloud集成 | 支持 | 支持 | 支持 | 支持 |
| 11 | 健康检查 | Client Beat | Keep Alive | TCP/HTTP/MYSQL/Client Beat | TCP/HTTP/gRPC/Cmd |
| 12 | 自动注销实例 | 支持 | 支持 | 支持 | 不支持 |
| 13 | 访问协议 | HTTP | TCP | HTTP/DNS | HTTP/DNS |
| 14 | 是否可用作配置中心 | 否 | 是 | 是 | 是 |
| 15 | 多数据中心 | 不支持 | 不支持 | 不支持 | 支持 |
| 16 | 跨注册中心同步 | 不支持 | 不支持 | 支持 | 支持 |
| 17 | Dubbo集成 | 不支持 | 支持 | 支持 | 不支持 |
| 18 | K8S集成 | 支持 | 支持 | 支持 | 支持 |
Nacos则支持平级关系和主从这两种集群架构,常用的是后者
我发现,集群架构和角色往往是一个注册中心的核心功能,搞清楚这两点,基本上对于这个注册中心已经掌握了一半了。来分别看看四个注册中心的集群角色吧~
1)Eureka:集群各节点都是平起平坐的关系,数据是相互复制的,因此各个节点都是主人角色如图,服务端Eureka-server会存储服务实例信息,通过复制实现服务实例信息在各个节点同步,并定期去检查服务实例信息状态;各个客户端也会通过健康检查等机制进行自我状态检查,要是信息有了变化,均会向服务Eureka-server发起请求Eureka-server则会分别处理这些状态变化,来保持实例信息的更新2)zookeeper:集群角色包含leader、follower以及observer三类
具体来说是一主多从结构,就是有一个leader,多个follower,以及只负责读操作、不参与选举的observer
下面是关于三个角色之间的关系图

a)首先图上是有client和server两大角色。client通过TCP与其中一个server建立连接。其中server分为leader、follower,以及observer三个角色
leader:负责投票的发起和决议
follower:同步leader的状态,参与leader选举。将写操作转发给leader,并参与“过半写成功”策略
observer:同步leader的状态,将写操作转发给Leader。不参加投票选举过程,也不参加写操作的“过半写成功”策略
b)当leader因为网络或者其他原因挂掉之后,会重新在follower里面选择一个新的leader。
c)observer 机器可以在不影响写性能的情况下提升集群的读性能。
3)cosul:集群角色包含server-leader、server以及client
这三个角色实际上可以分别对应zookeeper中的leader,follower以及observer。对了,这块第三种角色-client,千万要注意,它还是属于consul的服务端的一个节点角色,而不是consul的客户端哦client : consul的client模式的节点。接收到consul的客户端请求以后,不做处理,会转发到server-leader,也不会持久化信息server: consul的server模式的节点,功能和client都一样。唯一不同的是,它会把所有的信息持久化到本地,这样遇到故障,信息是可以被保留的server-leader: 名字就已经说明,这个server是所有服务端接节点的老大了,那么它自然负责的工作就多啦~ 它除了和普通的server模式的节点一样,需要进行信息持久化以外,还额外需要负责同步注册的信息给其它的server,同时也要负责各个节点的健康监测4)Nacos:包含leader、follower、candidate三类Leader:负责Client交互和log复制,同一时刻系统中最多存在1个Follower:被动响应请求RPC,从不主动发起请求RPC。接收到请求,会转发给leader处理Candidate:一种临时的角色,只存在于leader的选举阶段某个节点想要变成leader,那么就发起投票请求,同时自己变成candidate,如果选举成功,则变为candidate,否则退回为followera 集群启动后,初始节点状态都是 Follower 状态b 某个follower想要被选举成为leader,于是变成candidate(候选人)状态,向自己投票,并向其他follower发起投票请求
c 收到其他节点的投票响应以后,若超过半数的follower都投了自己,则投票成功,自己的状态变为leaderd 如果并没有收到大多数的选票,则进行新一轮的投票由于zooKeeper具有watcher机制,因此可以及时知道数据目录的状态变化,那么也就可以及时知道服务器节点以及所注册的实例的变化。我们可以通过这种监听机制,能够实时获取到某个服务器的故障或者我们比较关心的节点数据的更改(zookeeper的节点znode包含服务器节点和数据节点)其他三个注册中心没有这样的机制,只是可以通过管理端进行主动查看服务状态,并不能实时感知服务状态的变化
在理论计算机科学中,CAP定理,又被称作布鲁尔定理,它指出对于一个分布式计算系统来说,不可能同时满足以下三点:1)一致性(Consistency)注册中心的集群各个节点的数据信息完全一致2)可用性(Availability)每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据3)分区容错性(Partition tolerance)以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择根据定理,分布式系统只能满足三项中的两项,而不可能满足全部三项理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质Eureka :支持AP,即保障可用性和分区容错性
#false-注册永久实例,true-注册为临时实例
spring.cloud.nacos.discovery.ephemeral=false
除了consul不支持自动注销实例以外,其他三个注册中心均支持自动注销实例1)Eureka:默认情况下,如果Eureka Server在90秒内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(时间间隔可以配置)2)zookeeper:使用临时节点,依托于Session超时时间来实现TTL功能来实现自动注销。可以给每一个键或目录指定一个存活时限TTL,当指定的秒数过去以后,如果相应的键或目录没有得到更新,就会被自动从Etcd记录中移除3)Nacos:从 0.5.0 版本开始,用户通过客户端SDK注册的实例,将默认开启TTL功能,实例会默认每5秒向服务端发送一次心跳,如果Nacos服务端15秒内没有收到实例的心跳,则会将实例置为不健康,如果30秒没有收到心跳,则会将直接将实例删除TTL,是Time To Live的简称,意思为一条域名解析记录在DNS服务器中的存留时间1)Eureka :有雪崩保护。我们知道,当网络分区故障发生时,微服务与Eureka Server之间突然无法正常通信了,根据心跳机制,微服务将会被注销。那么这种心跳机制是不是就变得不太友好了?因为这种情况下微服务本身其实是健康的,本不应该注销这个微服务,因此Eureka就提供了一个自我保护机制,也就是雪崩保护机制;
当Eureka Server节点在短时间内丢失过多客户端(可能发生了网络分区故障),默认是15分钟内收到的续约低于原来的85%时,这个节点就会进入自我保护模式一旦进入该模式,Eureka Server仍能接收新服务的注册和查询请求,但是不会同步到其他节点上;同时也会保护服务注册表中的信息,不再移除注册列表中因为长时间没收到心跳而应该过期的服务。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式这样获取的数据的确有可能不是最新的,但Eureka的这种自我保护机制,极大地保证了Eureka的高可用特性4)nacos:有雪崩保护。为了防止因过多实例 (Instance) 不健康导致流量全部流向健康实例 (Instance) ,继而造成流量压力把健康实例 (Instance) 压垮并形成雪崩效应,应将健康保护阈值定义为一个 0 到 1 之间的浮点数当域名健康实例占总服务实例的比例小于该值时,无论实例是否健康,都会将这个实例返回给客户端。这样做虽然损失了一部分流量,但是保证了集群的剩余健康实例 (Instance) 能正常工作Eureka2.0不再维护了,而其他三个注册中心依旧在持续维护中,其中Nacos和Consul的社区应该说活跃度是最高的。从代码更新速度来讲,也是如此。分别看了一下eureka、zookeeper、nacos以及consul的代码更新记录
会发现,Eureka的更新频率相对来说,明显比较低,Zookeeper逐渐趋于成熟化,因此代码更新频率也很低,只是稍好于Eureka。而Nacos和Consul的更新频率明显很高,因此社区活跃度来说,Nacos和Consul还是很有优势的,因此对于未来的微服务项目的注册中心选型,更建议考虑这两种,更有保障一些
Eureka、Consul和Nacos都有现成的管理端zookeeper没有现成的管理端,但客户端也可以根据提供的API,很容易自己实现一个也控制台,比如zkui就是其中一个比较好用的zookeeper管理端Zookeeper:一般可以直接采用RPC的负载均衡 Nacos:采用权重/metadata/Selector 关于负载均衡策略,这块就不做过多介绍了,感兴趣的可以在网上找找~Eureka本身没有权限控制的机制,因此它需要与Spring Cloud Security来实现它的权限控制;nacos:使用RBAC实现节点权限控制-用户、角色、权限 四个注册中心,现均已支持Spring Cloud的集成Eureka:Eureka Server 与 Eureka Client 之间使用心跳机制来确定Eureka Client 的状态,默认情况下,服务器端与客户端的心跳保持正常,应用程序就会始终保持UP状态
Zookeeper:本身没有健康检查机制,需要消费者自己实现服务提供者的健康检查动作Nacos:Nacos 支持传输层(PIND 或 TCP)和应用层(如 HTTP、MySQL以及用户自定义)的监控检查,同时还支持类似于Eureka的心跳机制的健康检查健康检查,不得不说,是Consul的一个亮点特性了!Consul支持以下几种类型的健康检查:2)HTTP检查机制:通过向指定的URL发起GET请求,服务的状态依赖HTTP请求的状态码:429 - Too ManyRequests is a warning与使用Curl或是外部进程检查的健康检查机制相比,HTTP检查机制应该是首选的通过与指定的IP/hostname + 端口监理TCP连接保留了给定的TTL(生命周期)的最新的状态,这些状态必须通过HTTP接口定时进行更新,需要服务周期性汇报健康状态而Nacos和Consul除了支持HTTP协议访问以外,还支持DNS协议除了eureka不可以作为配置中心以外,其他三个注册中心均可以作为配置中心只有consul支持多数据中心,但其他注册中心都有方案部署为多数据中心zookeeper和Nacos支持Dubbo集成,Eureka和consul则暂不支持
好了,今天呢,我们主要通过18个方面,对四个注册中心做了分析比较,重新梳理比较了4个注册中心的核心特点。总得来说,四个注册中心各有优势consul和新晋的nacos的社区活跃度比较高,nacos可以同时支持AP和CP;consul则结合了zookeeper和nacos的诸多优点,还天然支持多数据中心;而zookeeper则又可以唯一感知到服务状态的实时变化;Eureka的自我保护机制使得它即使只剩下一台服务,也不影响正常运行,具有高可用性
需要结合业务场景来进行选择。比如说,对于金融类的业务场景,对于一致性要求更高,那么就会排除掉Eureka,然后根据易用性、性价比等其他方面再进行后续的选择;对于高可用比较注重的项目,如电商类项目,则可以选择Eurek或者Nacos,但再比较其他方面,Nacos不仅可以做注册中心,还可以作为架构中的配置中心,并且社区活跃度比较高,功能也日渐在完善,使用的人越来越多,因此综合来讲,就选择了Nacos具体选择的过程中,当然也会考虑这些因素之外的一些特点,包括人员的熟悉度等等,但肯定也是先考虑主要的特点,再去考虑这些不是那么重要的特点的