- 💌 所属专栏:【微服务】
- 😀 作 者:长安不及十里
- 💻 工作:目前从事电力行业开发
- 🌈 目标:全栈开发
- 🚀 个人简介:一个正在努力学技术的Java工程师,专注基础和实战分享 ,欢迎咨询!
- 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘
一 注册中心
1.1 注册中心原理
在微服务架构下,主要有三种角色:服务提供者(RPC Server)、服务消费者(RPC Client)和服务注册中心(Registry),三者的交互关系请看下面这张图,我来简单解释一下。
- RPC Server 提供服务,在启动时,根据服务发布文件 server.xml 中的配置的信息,向 Registry 注册自身服务,并向 Registry 定期发送心跳汇报存活状态。
- RPC Client 调用服务,在启动时,根据服务引用文件 client.xml 中配置的信息,向 Registry 订阅服务,把 Registry 返回的服务节点列表缓存在本地内存中,并与 RPC Sever 建立连接。
- 当 RPC Server 节点发生变更时,Registry 会同步变更,RPC Client 感知后会刷新本地内存中缓存的服务节点列表。
- RPC Client 从本地缓存的服务节点列表中,基于负载均衡算法选择一台 RPC Sever 发起调用。
1.2 注册中心主流技术
参考文章:
主流微服务注册中心浅析和对比-阿里云开发者社区
数据模型
- Zookeeper没有针对服务发现设计数据模型,它的数据是以一种更加抽象的树形K-V组织的,因此理论上可以存储任何语义的数据。
- 而Eureka或者Consul都是做到了实例级别的数据扩展,这可以满足大部分的场景,不过无法满足大规模和多环境的服务数据存储。
- Nacos在经过内部多年生产经验后提炼出的数据模型,则是一种服务-集群-实例的三层模型。
数据隔离
- Zookeeper、Consul和Eureka在开源层面都没有很明确的针对服务隔离的模型。
- Nacos则在一开始就考虑到如何让用户能够以多种维度进行数据隔离,同时能够平滑的迁移到阿里云上对应的商业化产品。
- Nacos提供了四层的数据逻辑隔离模型,用户账号对应的可能是一个企业或者独立的个体,这个数据一般情况下不会透传到服务注册中心。
- Nacos 1.0.0介绍的另外一个新特性是:临时实例和持久化实例,在定义上区分临时实例和持久化实例的关键是健康检查的方式,临时实例使用客户端上报模式,而持久化实例使用服务端反向探测模式。
数据一致性(重点理解)
- 数据一致性是分布式系统永恒的话题,Paxos协议的艰深更让数据一致性成为程序员大牛们吹水的常见话题。
- 目前来看基本可以归为两家:一种是基于Leader的非对等部署的单点写一致性,一种是对等部署的多写一致性。
- 这两种数据一致性协议有各自的使用场景,对服务注册的需求不同,就会导致使用不同的协议,在这里可以发现,Zookeeper在Dubbo体系下表现出的行为,其实采用Eureka的Renew机制更加合适,因为Dubbo服务往Zookeeper注册的就是临时节点,需要定时发心跳到Zookeeper来续约节点,并允许服务下线时,将Zookeeper上相应的节点摘除。Zookeeper使用ZAB协议虽然保证了数据的强一致,但是它的机房容灾能力的缺乏,无法适应一些大型场景。
- Nacos因为要支持多种服务类型的注册,并能够具有机房容灾、集群扩展等必不可少的能力,在1.0.0正式支持AP和CP两种一致性协议并存,1.0.0重构了数据的读写和同步逻辑,将与业务相关的CRUD与底层的一致性同步逻辑进行了分层隔离。然后将业务的读写(主要是写,因为读会直接使用业务层的缓存)抽象为Nacos定义的数据类型,调用一致性服务进行数据同步。在决定使用CP还是AP一致性时,使用一个代理,通过可控制的规则进行转发。
负载均衡
- 负载均衡严格的来说,并不算是传统注册中心的功能。一般来说服务发现的完整流程应该是先从注册中心获取到服务的实例列表,然后再根据自身的需求,来选择其中的部分实例或者按照一定的流量分配机制来访问不同的服务提供者,因此注册中心本身一般不限定服务消费者的访问策略。
- Eureka、Zookeeper包括Consul,本身都没有去实现可配置及可扩展的负载均衡机制,Eureka的负载均衡是由ribbon来完成的,而Consul则是由Fabio做负载均衡。
- Nacos试图做的是将服务端负载均衡与客户端负载均衡通过某种机制结合起来,提供用户扩展性,并给予用户充分的自主选择权和轻便的使用方式。负载均衡是一个很大的话题,当我们在关注注册中心提供的负载均衡策略时,需要注意该注册中心是否有我需要的负载均衡方式,使用方式是否复杂
健康检查
- Zookeeper和Eureka都实现了一种TTL的机制,就是如果客户端在一定时间内没有向注册中心发送心跳,则会将这个客户端摘除。
- Eureka做的更好的一点在于它允许在注册服务的时候,自定义检查自身状态的健康检查方法,这在服务实例能够保持心跳上报的场景下,是一种比较好的体验,在Dubbo和SpringCloud这两大体系内,也被培养成用户心智上的默认行为。
- Nacos也支持这种TTL机制,不过这与ConfigServer在阿里巴巴内部的机制又有一些区别,Nacos目前支持临时实例使用心跳上报方式维持活性,发送心跳的周期默认是5秒,Nacos服务端会在15秒没收到心跳后将实例设置为不健康,在30秒没收到心跳时将这个临时实例摘除。
性能与容量
- Zookeeper的容量,从存储节点数来说,可以达到百万级别。不过如上面所说,这并不代表容量的全部,当大量的实例上下线时,Zookeeper的表现并不稳定,同时在推送机制上的缺陷,会引起客户端的资源占用上升,从而性能急剧下降。
- Eureka在服务实例规模在5000左右的时候,就已经出现服务不可用的问题,甚至在压测的过程中,如果并发的线程数过高,就会造成Eureka crash。不过如果服务规模在1000上下,几乎目前所有的注册中心都可以满足。毕竟我们看到Eureka作为SpringCloud的注册中心,在国内也没有看到很广泛的对于容量或者性能的问题报告。
- Nacos在开源版本中,服务实例注册的支撑量约为100万,服务的数量可以达到10万以上。在实际的部署环境中,这个数字还会因为机器、网络的配置与JVM参数的不同,可能会有所差别。图9展示了Nacos在使用1.0.0版本进行压力测试后的结果总结,针对容量、并发、扩展性和延时等进行了测试和统计。
易用性
- Zookeeper的易用性是比较差的,Zookeeper的客户端使用比较复杂,没有针对服务发现的模型设计以及相应的API封装,需要依赖方自己处理。对多语言的支持也不太好,同时没有比较好用的控制台进行运维管理。
- Eureka和Nacos相比较Zookeeper而言,已经改善很多,这两个产品有针对服务注册与发现的客户端,也有基于SpringCloud体系的starter,帮助用户以非常低的成本无感知的做到服务注册与发现。同时还暴露标准的HTTP接口,支持多语言和跨平台访问。Eureka和Nacos都提供官方的控制台来查询服务注册情况。不过随着Eureka 2.0宣布停止开发,Eureka在针对用户使用上的优化后续应该不会再有比较大的投入。
- 而Nacos目前依然在建设中,除了目前支持的易用性特性以外,后续还会继续增强控制台的能力,增加控制台登录和权限的管控,监控体系和Metrics的暴露,持续通过官网等渠道完善使用文档,多语言SDK的开发等。
集群扩展性
- 集群扩展性的另一个方面是多地域部署和容灾的支持。当讲究集群的高可用和稳定性以及网络上的跨地域延迟要求能够在每个地域都部署集群的时候,我们现有的方案有多机房容灾、异地多活、多数据中心等。
- 首先是双机房容灾,基于Leader写的协议不做改造是无法支持的,这意味着Zookeeper不能在没有人工干预的情况下做到双机房容灾。在单机房断网情况下,使机房内服务可用并不难,难的是如何在断网恢复后做数据聚合,Zookeeper的单点写模式就会有断网恢复后的数据对账问题。
- Eureka的部署模式天然支持多机房容灾,因为Eureka采用的是纯临时实例的注册模式:不持久化、所有数据都可以通过客户端心跳上报进行补偿。上面说到,临时实例和持久化实例都有它的应用场景,为了能够兼容这两种场景。
- Nacos支持两种模式的部署,一种是和Eureka一样的AP协议的部署,这种模式只支持临时实例,可以完美替代当前的Zookeeper、Eureka,并支持机房容灾。另一种是支持持久化实例的CP模式,这种情况下不支持双机房容灾。
详细文章请参考:
主流微服务注册中心浅析和对比-阿里云开发者社区
注册中心对比和选型:Zookeeper、Eureka、Nacos、Consul和ETCD - 掘金