服务发现比较:Eureka vs Consul vs ZooKeeper

总结

Eureka Consul ZooKeeper
CAP AP CP CP
一致性算法 / Raft ZAB
服务健康检查 需配置 服务状态、内存、硬盘 长连接,KeepAlive
K-V 存储 / 支持 支持
自身监控 Metrics Metrics /
开发语言 Java Go Java

Consul

Consul 为服务发现、健康检查、K-V存储提供了一套开箱即用的解决方案。

Consul 官网中介绍了 Consul 的以下几个核心功能:

  • 服务发现(Service Discovery):提供 HTTP 与DNS 两种方式。
  • 健康检查(Health Checking):提供多种健康检查方式,比如 HTTP 状态码、内存使用情况、硬盘等等。
  • 键值存储(KV Store):可以作为服务配置中心使用,类似 Spring Cloud Config。
  • 加密服务通信(Secure Service Communication)
  • 多数据中心(Multi Datacenter):Consul 通过 WAN 的 Gossip 协议,完成跨数据中心的同步。

“In CAP terms, Consul uses a CP architecture, favoring consistency over availability. “
Consul 官网中明确指出 Consul 是 CP 的。

Consul 的架构

consul

  • Data Center:数据中心,每个数据中心的节点被称为 Agent
  • Client:负责健康检查与转发所有 RPC 请求至 Server 节点
  • Server:负责响应 RPC 请求、参与 Raft 选举、维护集群状态和转发请求给 Leader 或其他 Data Center
  • Leader Server:主 Server 节点,Leader 负责处理所有的查询和事务
  • Foller Server:从 Server 节点,所有 Foller 接收到的 RPC请求都会被转发至 Master

Eureka

Eureka 是 Spring Cloud NetFlix 默认的服务发现框架,但目前 2.0 版本已闭源,只剩下 1.9 版本的处于维护状态。

Eureka使用尽力而为同步的方式提供提供弱一致的服务列表。当一个服务注册时,Eureka 会尝试将其同步到其他节点上,但不提供一致性的保证。 因此,Eureka 可以提供过时的或是已不存在的服务列表(在服务发现场景下,返回旧的总比什么也不返回好)。

Eureka 的架构

eureka

  • Application Service:微服务的提供者
  • Application Client:微服务的消费者
  • Eureka Server:注册中心,提供服务注册与发现功能
  • Replicate:不同 Eureka Server 间的同步,无法保证强一致性
  • Renew:服务续约,通过发送心跳到 Eureka Server 来保持有效性(默认周期 30s),当在一定时长(默认90s)内 Eureka Server 没有收到 Eureka Client 的心跳,将该实例的信息从注册表中删除
  • Cancel:服务下线,Eureka Client 主动向 Eureka Server 请求注销,Eureka Server 将该实例删除

注意,Eureka 有一套缓存机制。Eureka Client 会缓存 Eureka Server 中的服务注册表信息。即使所有的 Eureka Server 节点都失效,服务消费者依然可以使用缓存中的信息找到服务提供者。Ereka Client 默认每 30s 发送一次请求来更新缓存。

Eureka 的自我保护模式

如果在 15分钟内超过85%的客户端节点都没有正常的心跳,那么 Eureka 就会认为客户端与注册中心出现了网络故障(出现网络分区),进入自我保护机制。

此时:

  • Eureka Server 会保护服务注册表中的信息,不再删除服务。这是由于如果出现网络分区导致其他微服务和该 Eureka Server 无法通信,Eureka Server 就会判定这些微服务失效,但很可能这些微服务都是健康的。
  • Eureka Server 仍能接受新服务的注册和查询请求,但这些数据不会被同步到其他节点。
  • 当网络恢复时,这个 Eureka Server 节点的数据会被同步到其他节点中。

优点:

  • Eureka Server 可以很好的应对因网络故障导致部分节点失联的情况,而不会像 ZK 那样如果有一半不可用的情况会导致整个集群不可用。

ZooKeeper

严格来说,ZookKeeper 并不只是作为服务发现框架使用的。ZookKeeper 官网是这么介绍的:

“ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. “

可以看出,服务发现只是 ZooKeeper 中的其中一个功能而已。

ZooKeeper 只提供了原始的 K-V 存储,要想实现服务发现需要自己编写相关代码或借助其他工具。

CAP

CAP原则指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)不能同时成立,最多只能同时实现以上两点。

  • 一致性(C):要求在同一时刻,分布式系统中的所有数据都处于同一状态。
  • 可用性(A):在系统集群的一部分节点宕机后,系统依然能够响应用户的请求。
  • 分区容错性(P):在网络区间通信出现失败,系统能够容忍。

由于网络的不稳定性,网络分区是不可避免的,所以分区容错性通常来说是必须需要实现的。

服务发现中的 CAP

当向服务注册中心查询服务列表时,返回过时的的服务列表是可以接受,但不能接受服务注册中心不可用。即服务发现对可用性(A)的追求是高于一致性(P)的,即服务注册中心应该是 AP 的。

在 ZooKeeper 中,如果 master 节点失效,剩余节点便会触发 Leader 选举,但在选举期间,整个 ZK 集群都是不可用的。尽管 Dubbo 中为了解决这个问题而引入了本地缓存,但也是部分解决问题,例如在一个网络分区中节点数量达不到选举 Leader 的半数法定人数情况下,这个分区中的所有节点将从 ZK 中断开,不再提供服务,即使这些节点都是健康的。即 ZooKeeper 是无法保证可用性的。服务注册的过程也是一样的,需要超过半数的法定人数节点数量都写入成功才能注册服务。Consul 中的过程与 上述 ZK 的类似。

而在 Eureka 中,如果某个服务注册中心挂了,Eureka 不会有类似于 ZooKeeper 与 Consul 中的重新选举 Leader 过程,客户端的请求会自动切换到新的节点(满足了可用性A)。当挂掉的节点恢复健康,Eureka 又会将它加入回集群中。

Watch

Watch 即客户端观察到服务提供者变化,Zookeeper 支持服务器端推送变化, Eureka 1 和 Consul 则是通过长轮询的方式来实现感知服务变化,无法实时获取服务信息的变化。

三者的使用情况

1

2

  • 本文作者: Marticles
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!