一、注册中心本质及关键设计考量
注册中心最本质的功能可以看成是一个Query函数 Si = F(service-name)
,以 service-name
为查询参数,service-name
对应的服务的可用的 endpoints (ip:port)
列表为返回值.
CAP 和 BASE 理论相信读者都已经耳熟能详,其业已成了指导分布式系统及互联网应用构建的关键原则之一,那么注册中心应该是 CP 还是 AP 系统?
1.先来看看关键数据 endpoints (ip:port)
不一致性带来的影响,即 CAP 中的 C 不满足带来的后果 :
如上图所示,如果一个 svcB 部署了10个节点 (副本/Replica),如果对于同一个服务名 svcB, 调用者 svcA 的2个节点的2次查询返回了不一致的数据,例如: S1 = { ip1,ip2,ip3…,ip9 }, S2 = { ip2,ip3,….ip10 }, 那么这次不一致带来的影响是什么?
结果就是,svcB 的各个节点流量会有一点不均衡。
ip1和ip10相对其它8个节点{ip2…ip9},请求流量小了一点,但很明显,在分布式系统中,即使是对等部署的服务,因为请求到达的时间,硬件的状态,操作系统的调度,虚拟机的 GC 等,任何一个时间点,这些对等部署的节点状态也不可能完全一致,而流量不一致的情况下,只要注册中心在SLA承诺的时间内(例如1s内)将数据收敛到一致状态(即满足最终一致),流量将很快趋于统计学意义上的一致,所以注册中心以最终一致的模型设计在生产实践中完全可以接受。
2.接下来我们看一下网络分区(Network Partition)情况下注册中心不可用对服务调用产生的影响,即 CAP 中的A不满足时带来的影响。
当机房3出现网络分区(Network Partitioned)的时候,即机房3在网络上成了孤岛,我们知道虽然整体 ZooKeeper 服务是可用的,但是节点ZK5是不可写的,因为联系不上 Leader。
也就是说,这时候机房3的应用服务 svcB 是不可以新部署,重新启动,扩容或者缩容的,但是站在网络和服务调用的角度看,机房3的 svcA 虽然无法调用机房1和机房2的 svcB,但是与机房3的svcB之间的网络明明是 OK 的啊,为什么不让我调用本机房的服务?
现在因为注册中心自身为了保脑裂(P)下的数据一致性(C)而放弃了可用性,导致了同机房的服务之间出现了无法调用,这是绝对不允许的!可以说在实践中,注册中心不能因为自身的任何原因破坏服务之间本身的可连通性,这是注册中心设计应该遵循的铁律! 后面在注册中心客户端灾容上我们还会继续讨论。
同时我们再考虑一下这种情况下的数据不一致性,如果机房1,2,3之间都成了孤岛,那么如果每个机房的svcA都只拿到本机房的 svcB 的ip列表,也即在各机房svcB 的ip列表数据完全不一致,影响是什么?
其实没啥大影响,只是这种情况下,全都变成了同机房调用,我们在设计注册中心的时候,有时候甚至会主动利用这种注册中心的数据可以不一致性,来帮助应用主动做到同机房调用,从而优化服务调用链路 RT 的效果!
通过以上我们的阐述可以看到,在 CAP 的权衡中,注册中心的可用性比数据强一致性更宝贵,所以整体设计更应该偏向 AP,而非 CP,数据不一致在可接受范围,而P下舍弃A却完全违反了注册中心不能因为自身的任何原因破坏服务本身的可连通性的原则。
综上,注册中心应该是AP模型而不是CP模型。
二、注册中心现状
下表是常见的注册中心对比:
Feature | Consul | Zookeeper | Etcd | Eureka |
服务健康检查 | 服务状态,内存,硬盘等 | (弱)长连接,keepalive | 连接心跳 | 可配支持 |
多数据中心 | 支持 | — | — | — |
kv存储服务 | 支持 | 支持 | 支持 | — |
一致性 | raft | paxos | raft | — |
CAP定理 | CP | CP | CP | AP |
使用接口(多语言能力) | 支持http和dns | 客户端 | http/grpc | http(sidecar) |
watch支持 | 全量/支持long polling | 支持 | 支持 long polling | 支持 long polling/大部分增量 |
自身监控 | metrics | — | metrics | metrics |
安全 | acl /https | acl | https支持(弱) | — |
Spring Cloud集成 | 已支持 | 已支持 | 已支持 | 已支持 |
由上面的结论可知,最适合做注册中心的就是Eureka
Eureka是Spring Cloud Netflix微服务套件中的一部分,可以与Springboot构建的微服务很容易的整合起来。
Eureka包含了服务器端和客户端组件。服务器端,也被称作是服务注册中心,用于提供服务的注册与发现。Eureka支持高可用的配置,当集群中有分片出现故障时,Eureka就会转入自动保护模式,它允许分片故障期间继续提供服务的发现和注册,当故障分片恢复正常时,集群中其他分片会把他们的状态再次同步回来。
客户端组件包含服务消费者与服务生产者。在应用程序运行时,Eureka客户端向注册中心注册自身提供的服务并周期性的发送心跳来更新它的服务租约。同时也可以从服务端查询当前注册的服务信息并把他们缓存到本地并周期性的刷新服务状态。
然而 Eureka 的 GitHub Wiki 上显示其 2.0 版本的开源工作已经停止。
这意味着如果开发者继续使用作为 2.x 分支上现有工作 repo 一部分发布的代码库和工件,则将自负风险。
三、注册中心的新选择
Nacos是阿里巴巴集团开源的一个易于使用的平台,专为动态服务发现,配置和服务管理而设计。它可以轻松构建云本机应用程序和微服务平台。
Nacos基本上支持现在所有类型的服务,例如,Dubbo / gRPC服务,Spring Cloud RESTFul服务或Kubernetes服务。
使用Eureka注册中心的,并且担心Eureka闭源的开发者们,可以将注册中心修改为Nacos。
Nacos 的关键特性包括:
-
服务发现和服务健康监测
Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用 原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后,服务消费者可以使用DNS TODO 或HTTP&API查找和发现服务。
Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求。Nacos 支持传输层 (PING 或 TCP)和应用层 (如 HTTP、MySQL、用户自定义)的健康检查。 对于复杂的云环境和网络拓扑环境中(如 VPC、边缘网络等)服务的健康检查,Nacos 提供了 agent 上报模式和服务端主动检测2种健康检查模式。Nacos 还提供了统一的健康检查仪表盘,帮助开发者根据健康状态管理服务的可用性及流量。
-
动态配置服务
动态配置服务可以让您以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。
动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。
配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
Nacos 提供了一个简洁易用的UI (控制台样例 Demo) 帮助您管理所有的服务和应用的配置。Nacos 还提供包括配置版本跟踪、金丝雀发布、一键回滚配置以及客户端配置更新状态跟踪在内的一系列开箱即用的配置管理特性,帮助开发者更安全地在生产环境中管理配置变更和降低配置变更带来的风险。
-
动态 DNS 服务
动态 DNS 服务支持权重路由,让开发者更容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单DNS解析服务。动态DNS服务还能让开发者更容易地实现以 DNS 协议为基础的服务发现,以帮助开发者消除耦合到厂商私有服务发现 API 上的风险。
Nacos 提供了一些简单的 DNS APIs TODO 帮助开发者管理服务的关联域名和可用的 IP:PORT 列表.
-
服务及其元数据管理
Nacos 能让开发者从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的 metrics 统计数据。