我们已经分别单独讲了这四种注册中心,但是在实际的项目选型中,该如何考虑选择合适的注册中心呢?
我在网上找了很多资料,但都基本不是最新的,比如说几乎所有的资料都还在说只有Eureka支持Spring Cloud的集成,其他注册中心均不支持Spring Cloud。因此,就想要自己写一篇最新最全的注册中心的特点比较的文章,来帮助自己以及亲爱的粉丝们重新梳理他们的特点,以保证以更全方位的考虑来进行项目选型
1 集群结构
Eureka的集群架构本身就是平级结构
zookeeper和consul则均为主从结构
Nacos则支持平级关系和主从这两种集群架构,常用的是后者
具体架构是怎样的,可以继续往下看~
2 集群角色
我发现,集群架构和角色往往是一个注册中心的核心功能,搞清楚这两点,基本上对于这个注册中心已经掌握了一半了。来分别看看四个注册中心的集群角色吧~
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,否则退回为follower
具体流程如下图所示:
a 集群启动后,初始节点状态都是 Follower 状态
b 某个follower想要被选举成为leader,于是变成candidate(候选人)状态,向自己投票,并向其他follower发起投票请求
c 收到其他节点的投票响应以后,若超过半数的follower都投了自己,则投票成功,自己的状态变为leader
d 如果并没有收到大多数的选票,则进行新一轮的投票
3 是否可以及时知道服务状态变化
由于zooKeeper具有watcher机制,因此可以及时知道数据目录的状态变化,那么也就可以及时知道服务器节点以及所注册的实例的变化。我们可以通过这种监听机制,能够实时获取到某个服务器的故障或者我们比较关心的节点数据的更改(zookeeper的节点znode包含服务器节点和数据节点)
其他三个注册中心没有这样的机制,只是可以通过管理端进行主动查看服务状态,并不能实时感知服务状态的变化
4 一致性协议(CAP)
首先,我们再复习一下CAP原理(参考维基百科)
在理论计算机科学中,CAP定理,又被称作布鲁尔定理,它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
1)一致性(Consistency)注册中心的集群各个节点的数据信息完全一致
2)可用性(Availability)每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据
3)分区容错性(Partition tolerance)以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择
根据定理,分布式系统只能满足三项中的两项,而不可能满足全部三项
理解CAP理论的最简单方式是想象两个节点分处分区两侧。允许至少一个节点更新状态会导致数据不一致,即丧失了C性质。如果为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点可以互相通信,才能既保证C又保证A,这又会导致丧失P性质
而四个注册中心,对一致性协议的支持情况如下:
Eureka :支持AP,即保障可用性和分区容错性
Zookeeper:支持CP,即保障一致性和分区容错性
consul:支持CP,即保障一致性和分区容错性
nacos:支持AP和CP两种模式。可以分别支持AP和CP两种场景
C是所有节点在同一时间看到的数据是一致的;A是所有的请求都会收到响应。一个保证一致性,一个保证可用性。那么,对于Nacos,如何选择使用哪种模式呢?
1)一般来说,如果不需要存储服务级别的信息,且服务实例是通过Nacos-client注册,并能够保持心跳上报,那么就可以选择AP模式。AP模式为了服务的可用性而减弱了一致性,因此AP模式下只能注册临时实例
2)如果需要在服务级别编辑或存储配置信息,那么CP是必须,K8S服务和DNS服务则适用于CP服务,CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误
那么该如何切换这两种模式呢?
1)执行如下命令:
curl -X PUT `$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
2)同时微服务的bootstrap.properties 需配置如下选项指明注册为临时/永久实例
#false-注册永久实例,true-注册为临时实例
spring.cloud.nacos.discovery.ephemeral=false
5 自动注销实例
除了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秒没有收到心跳,则会将直接将实例删除
Tips:
TTL,是Time To Live的简称,意思为一条域名解析记录在DNS服务器中的存留时间
6 雪崩保护
1)Eureka :有雪崩保护。我们知道,当网络分区故障发生时,微服务与Eureka Server之间突然无法正常通信了,根据心跳机制,微服务将会被注销。那么这种心跳机制是不是就变得不太友好了?因为这种情况下微服务本身其实是健康的,本不应该注销这个微服务,因此Eureka就提供了一个自我保护机制,也就是雪崩保护机制;
a)条件:
当Eureka Server节点在短时间内丢失过多客户端(可能发生了网络分区故障),默认是15分钟内收到的续约低于原来的85%时,这个节点就会进入自我保护模式
b)动作:
一旦进入该模式,Eureka Server仍能接收新服务的注册和查询请求,但是不会同步到其他节点上;同时也会保护服务注册表中的信息,不再移除注册列表中因为长时间没收到心跳而应该过期的服务。当网络故障恢复后,该Eureka Server节点会自动退出自我保护模式
这样获取的数据的确有可能不是最新的,但Eureka的这种自我保护机制,极大地保证了Eureka的高可用特性
2)Zookeeper:没有雪崩保护
3)consul:没有雪崩保护
4)nacos:有雪崩保护。为了防止因过多实例 (Instance) 不健康导致流量全部流向健康实例 (Instance) ,继而造成流量压力把健康实例 (Instance) 压垮并形成雪崩效应,应将健康保护阈值定义为一个 0 到 1 之间的浮点数
当域名健康实例占总服务实例的比例小于该值时,无论实例是否健康,都会将这个实例返回给客户端。这样做虽然损失了一部分流量,但是保证了集群的剩余健康实例 (Instance) 能正常工作
7 社区是否活跃
Eureka2.0不再维护了,而其他三个注册中心依旧在持续维护中,其中Nacos和Consul的社区应该说活跃度是最高的。从代码更新速度来讲,也是如此。分别看了一下eureka、zookeeper、nacos以及consul的代码更新记录
1)eureka
2)zookeeper
3)nacos
4)consul
会发现,Eureka的更新频率相对来说,明显比较低,Zookeeper逐渐趋于成熟化,因此代码更新频率也很低,只是稍好于Eureka。而Nacos和Consul的更新频率明显很高,因此社区活跃度来说,Nacos和Consul还是很有优势的,因此对于未来的微服务项目的注册中心选型,更建议考虑这两种,更有保障一些
8 是否有管理端
Eureka、Consul和Nacos都有现成的管理端
zookeeper没有现成的管理端,但客户端也可以根据提供的API,很容易自己实现一个也控制台,比如zkui就是其中一个比较好用的zookeeper管理端
9 负载均衡策略
Eureka:使用ribbon实现
Zookeeper:一般可以直接采用RPC的负载均衡
Nacos:采用权重/metadata/Selector
Consul:使用Fabio
关于负载均衡策略,这块就不做过多介绍了,感兴趣的可以在网上找找~
10 权限控制
Eureka本身没有权限控制的机制,因此它需要与Spring Cloud Security来实现它的权限控制;
zookeeper:使用ACL实现节点权限控制
nacos:使用RBAC实现节点权限控制-用户、角色、权限
consul:使用ACL实现节点权限控制
11 Spring Cloud集成
四个注册中心,现均已支持Spring Cloud的集成
12 健康检查
Eureka:Eureka Server 与 Eureka Client 之间使用心跳机制来确定Eureka Client 的状态,默认情况下,服务器端与客户端的心跳保持正常,应用程序就会始终保持UP状态
Zookeeper:本身没有健康检查机制,需要消费者自己实现服务提供者的健康检查动作
Nacos:Nacos 支持传输层(PIND 或 TCP)和应用层(如 HTTP、MySQL以及用户自定义)的监控检查,同时还支持类似于Eureka的心跳机制的健康检查
Consul:TCP/HTTP/gRPC/Cmd
健康检查,不得不说,是Consul的一个亮点特性了!Consul支持以下几种类型的健康检查:
1)脚本检查机制:通过执行程序外的脚本
2)HTTP检查机制:通过向指定的URL发起GET请求,服务的状态依赖HTTP请求的状态码:
2xx - passing
429 - Too ManyRequests is a warning
other - failure
与使用Curl或是外部进程检查的健康检查机制相比,HTTP检查机制应该是首选的
3)TCP检查机制
通过与指定的IP/hostname + 端口监理TCP连接
4)TTL检查机制
保留了给定的TTL(生命周期)的最新的状态,这些状态必须通过HTTP接口定时进行更新,需要服务周期性汇报健康状态
5)Docker检查机制
依赖触发一同被打包进容器的外部应用程序
13 访问协议
Eureka采用HTTP协议进行访问
Zookeeper采用TCP进行访问
而Nacos和Consul除了支持HTTP协议访问以外,还支持DNS协议
14 是否可用作配置中心
除了eureka不可以作为配置中心以外,其他三个注册中心均可以作为配置中心
15 多数据中心
只有consul支持多数据中心,但其他注册中心都有方案部署为多数据中心
16 跨注册中心同步
nacos和consul支持跨注册中心同步
17 Dubbo集成
zookeeper和Nacos支持Dubbo集成,Eureka和consul则暂不支持
18 K8S集成
四个注册中心均支持k8s集成
三 总结
总而言之
好了,今天呢,我们主要通过18个方面,对四个注册中心做了分析比较,重新梳理比较了4个注册中心的核心特点。总得来说,四个注册中心各有优势
consul和新晋的nacos的社区活跃度比较高,nacos可以同时支持AP和CP;consul则结合了zookeeper和nacos的诸多优点,还天然支持多数据中心;而zookeeper则又可以唯一感知到服务状态的实时变化;Eureka的自我保护机制使得它即使只剩下一台服务,也不影响正常运行,具有高可用性
那么选择的时候,究竟应该如何选择呢?
需要结合业务场景来进行选择。比如说,对于金融类的业务场景,对于一致性要求更高,那么就会排除掉Eureka,然后根据易用性、性价比等其他方面再进行后续的选择;对于高可用比较注重的项目,如电商类项目,则可以选择Eurek或者Nacos,但再比较其他方面,Nacos不仅可以做注册中心,还可以作为架构中的配置中心,并且社区活跃度比较高,功能也日渐在完善,使用的人越来越多,因此综合来讲,就选择了Nacos
具体选择的过程中,当然也会考虑这些因素之外的一些特点,包括人员的熟悉度等等,但肯定也是先考虑主要的特点,再去考虑这些不是那么重要的特点的
嗯,就这样。每天学习一点,时间会见证你的强大~
网友评论