注册中心不知选哪个?Zookeeper、Eureka、Nacos、Consul和Etcd 5种全方位剖析对比

📅 2026/8/13 23:46:04
注册中心不知选哪个?Zookeeper、Eureka、Nacos、Consul和Etcd 5种全方位剖析对比
本文给大家讲解 5 种常用的注册中心对比其流程和原理无论是面试还是技术选型都非常有帮助。对于注册中心在写这篇文章前我其实只对 ETCD 有比较深入的了解但是对于 Zookeeper 和其他的注册中心了解甚少甚至都没有考虑过 ETCD 和 Zookeeper 是否适合作为注册中心。经过近 2 周的学习原来注册中心除了 ETCD 和 Zookeeper常用的还有 Eureka、Nacos、Consul。下面我们就对这些常用的注册中心初探它们的异同便于后续技术选型。注册中心基本概念| 什么是注册中心注册中心主要有三种角色服务提供者RPC Server在启动时向 Registry 注册自身服务并向 Registry 定期发送心跳汇报存活状态。服务消费者RPC Client在启动时向 Registry 订阅服务把 Registry 返回的服务节点列表缓存在本地内存中并与 RPC Sever 建立连接。服务注册中心Registry用于保存 RPC Server 的注册信息当 RPC Server 节点发生变更时Registry 会同步变更RPC Client 感知后会刷新本地 内存中缓存的服务节点列表。最后RPC Client 从本地缓存的服务节点列表中基于负载均衡算法选择一台 RPC Sever 发起调用。| 注册中心需要实现功能根据注册中心原理的描述注册中心必须实现以下功能偷个懒直接贴幅图| 注册中心基础扫盲这块知识如果大家已经知道可以直接跳过主要是为了扫盲。①CAP 理论CAP 理论是分布式架构中重要理论一致性(Consistency)所有节点在同一时间具有相同的数据可用性(Availability) 保证每个请求不管成功或者失败都有响应分隔容忍(Partition tolerance) 系统中任意信息的丢失或失败不会影响系统的继续运作。关于 P 的理解我觉得是在整个系统中某个部分挂掉了或者宕机了并不影响整个系统的运作或者说使用而可用性是某个系统的某个节点挂了但是并不影响系统的接受或者发出请求。CAP 不可能都取只能取其中两个的原因如下如果 C 是第一需求的话那么会影响 A 的性能因为要数据同步不然请求结果会有差异但是数据同步会消耗时间期间可用性就会降低。如果 A 是第一需求那么只要有一个服务在就能正常接受请求但是对于返回结果变不能保证原因是在分布式部署的时候数据一致的过程不可能想切线路那么快。再如果同时满足一致性和可用性那么分区容错就很难保证了也就是单点也是分布式的基本核心。②分布式系统协议一致性协议算法主要有 Paxos、Raft、ZAB。Paxos 算法是 Leslie Lamport 在 1990 年提出的一种基于消息传递的一致性算法非常难以理解基于 Paxos 协议的数据同步与传统主备方式最大的区别在于Paxos 只需超过半数的副本在线且相互通信正常就可以保证服务的持续可用且数据不丢失。Raft 是斯坦福大学的 Diego Ongaro、John Ousterhout 两个人以易理解为目标设计的一致性算法已经有了十几种语言的 Raft 算法实现框架较为出名的有 etcdGoogle 的 Kubernetes 也是用了 etcd 作为他的服务发现框架。Raft 是 Paxos 的简化版与 Paxos 相比Raft 强调的是易理解、易实现Raft 和 Paxos 一样只要保证超过半数的节点正常就能够提供服务。ZooKeeper Atomic BroadcastZABZooKeeper 原子消息广播协议是 ZooKeeper 实现分布式数据一致性的核心算法。ZAB 借鉴 Paxos 算法但又不像 Paxos 算法那样是一种通用的分布式一致性算法它是一种特别为 ZooKeeper 专门设计的支持崩溃恢复的原子广播协议。常用注册中心这里主要介绍 5 种常用的注册中心分别为 Zookeeper、Eureka、Nacos、Consul 和 ETCD。| Zookeeper这个说起来有点意思的是官方并没有说他是一个注册中心但是国内 Dubbo 场景下很多都是使用 Zookeeper 来完成了注册中心的功能。当然这有很多历史原因这里我们就不追溯了。ZooKeeper 是非常经典的服务注册中心中间件在国内环境下由于受到 Dubbo 框架的影响大部分情况下认为 Zookeeper 是 RPC 服务框架下注册中心最好选择。随着 Dubbo 框架的不断开发优化和各种注册中心组件的诞生即使是 RPC 框架现在的注册中心也逐步放弃了 ZooKeeper。在常用的开发集群环境中ZooKeeper 依然起到十分重要的作用Java 体系中大部分的集群环境都是依赖 ZooKeeper 管理服务的各个节点。①Zookeeper 如何实现注册中心Zookeeper 可以充当一个服务注册表Service Registry让多个服务提供者形成一个集群让服务消费者通过服务注册表获取具体的服务访问地址IP端口去访问具体的服务提供者。如下图所示每当一个服务提供者部署后都要将自己的服务注册到 Zookeeper 的某一路径上: /{service}/{version}/{ip:port} 。比如我们的 HelloWorldService 部署到两台机器那么 Zookeeper 上就会创建两条目录/HelloWorldService/1.0.0/100.19.20.01:16888/HelloWorldService/1.0.0/100.19.20.02:16888这么描述有点不好理解下图更直观在 Zookeeper 中进行服务注册实际上就是在 Zookeeper 中创建了一个 znode 节点该节点存储了该服务的 IP、端口、调用方式协议、序列化方式等。该节点承担着最重要的职责它由服务提供者(发布服务时)创建以供服务消费者获取节点中的信息从而定位到服务提供者真正网络拓扑位置以及得知如何调用。RPC 服务注册/发现过程简述如下服务提供者启动时会将其服务名称IP 地址注册到配置中心。服务消费者在第一次调用服务时会通过注册中心找到相应的服务的 IP 地址列表并缓存到本地以供后续使用。当消费者调用服务时不会再去请求注册中心而是直接通过负载均衡算法从 IP 列表中取一个服务提供者的服务器调用服务。当服务提供者的某台服务器宕机或下线时相应的 IP 会从服务提供者 IP 列表中移除。同时注册中心会将新的服务 IP 地址列表发送给服务消费者机器缓存在消费者本机。当某个服务的所有服务器都下线了那么这个服务也就下线了。同样当服务提供者的某台服务器上线时注册中心会将新的服务 IP 地址列表发送给服务消费者机器缓存在消费者本机。服务提供方可以根据服务消费者的数量来作为服务下线的依据。Zookeeper 提供了“心跳检测”功能它会定时向各个服务提供者发送一个请求实际上建立的是一个 socket 长连接如果长期没有响应服务中心就认为该服务提供者已经“挂了”并将其剔除。比如 100.100.0.237 这台机器如果宕机了那么 Zookeeper 上的路径就会只剩 /HelloWorldService/1.0.0/100.100.0.238:16888。Zookeeper 的 Watch 机制其实就是一种推拉结合的模式服务消费者会去监听相应路径/HelloWorldService/1.0.0一旦路径上的数据有任务变化增加或减少Zookeeper 只会发送一个事件类型和节点信息给关注的客户端而不会包括具体的变更内容所以事件本身是轻量级的这就是推的部分。收到变更通知的客户端需要自己去拉变更的数据这就是拉的部分。②Zookeeper 不适合作为注册中心作为一个分布式协同服务ZooKeeper 非常好但是对于 Service 发现服务来说就不合适了因为对于 Service 发现服务来说就算是返回了包含不实的信息的结果也比什么都不返回要好。所以当向注册中心查询服务列表时我们可以容忍注册中心返回的是几分钟以前的注册信息但不能接受服务直接 down 掉不可用。但是 zk 会出现这样一种情况当 master 节点因为网络故障与其他节点失去联系时剩余节点会重新进行 leader 选举。问题在于选举 leader 的时间太长30 ~ 120s, 且选举期间整个 zk 集群都是不可用的这就导致在选举期间注册服务瘫痪。在云部署的环境下因网络问题使得 zk 集群失去 master 节点是较大概率会发生的事虽然服务能够最终恢复但是漫长的选举时间导致的注册长期不可用是不能容忍的。所以说作为注册中心可用性的要求要高于一致性在 CAP 模型中Zookeeper 整体遵循一致性CP原则即在任何时候对 Zookeeper 的访问请求能得到一致的数据结果但是当机器下线或者宕机时不能保证服务可用性。那为什么 Zookeeper 不使用最终一致性AP模型呢因为这个依赖 Zookeeper 的核心算法是 ZAB所有设计都是为了强一致性。这个对于分布式协调系统完全没没有毛病但是你如果将 Zookeeper 为分布式协调服务所做的一致性保障用在注册中心或者说服务发现场景这个其实就不合适。| EurekaEureka 架构图什么上面这幅图看起来很复杂那我给你贴个简化版Eureka 特点可用性AP 原则Eureka 在设计时就紧遵 AP 原则Eureka 的集群中只要有一台 Eureka 还在就能保证注册服务可用只不过查到的信息可能不是最新的不保证强一致性。去中心化架构Eureka Server 可以运行多个实例来构建集群不同于 ZooKeeper 的选举 leader 的过程Eureka Server 采用的是 Peer to Peer 对等通信。这是一种去中心化的架构无 master/slave 之分每一个 Peer 都是对等的。节点通过彼此互相注册来提高可用性每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。请求自动切换在集群环境中如果某台 Eureka Server 宕机Eureka Client 的请求会自动切换到新的 Eureka Server 节点上当宕机的服务器重新恢复后Eureka 会再次将其纳入到服务器集群管理之中。节点间操作复制当节点开始接受客户端请求时所有的操作都会在节点间进行复制操作将请求复制到该 Eureka Server 当前所知的其它所有节点中。自动注册心跳当一个新的 Eureka Server 节点启动后会首先尝试从邻近节点获取所有注册列表信息并完成初始化。Eureka Server 通过 getEurekaServiceUrls() 方法获取所有的节点并且会通过心跳契约的方式定期更新。自动下线默认情况下如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳默认周期为 30 秒Eureka Server 将会注销该实例默认为 90 秒eureka.instance.lease-expiration-duration-in-seconds 进行自定义配置。保护模式当 Eureka Server 节点在短时间内丢失过多的心跳时那么这个节点就会进入自我保护模式。除了上述特点Eureka 还有一种自我保护机制如果在 15 分钟内超过 85% 的节点都没有正常的心跳那么 Eureka 就认为客户端与注册中心出现了网络故障。此时会出现以下几种情况Eureka不再从注册表中移除因为长时间没有收到心跳而过期的服务Eureka仍然能够接受新服务注册和查询请求但是不会被同步到其它节点上即保证当前节点依然可用当网络稳定时当前实例新注册的信息会被同步到其它节点中。了解完 Eureka 核心概念自我保护机制以及集群内的工作原理后我们来整体梳理一下 Eureka 的工作流程Eureka Server 启动成功等待服务端注册。在启动过程中如果配置了集群集群之间定时通过 Replicate 同步注册表每个 Eureka Server 都存在独立完整的服务注册表信息。Eureka Client 启动时根据配置的 Eureka Server 地址去注册中心注册服务。Eureka Client 会每 30s 向 Eureka Server 发送一次心跳请求证明客户端服务正常。当 Eureka Server 90s 内没有收到 Eureka Client 的心跳注册中心则认为该节点失效会注销该实例。单位时间内 Eureka Server 统计到有大量的 Eureka Client 没有上送心跳则认为可能为网络异常进入自我保护机制不再剔除没有上送心跳的客户端。当 Eureka Client 心跳请求恢复正常之后Eureka Server 自动退出自我保护模式。Eureka Client 定时全量或者增量从注册中心获取服务注册表并且将获取到的信息缓存到本地。服务调用时Eureka Client 会先从本地缓存找寻调取的服务。如果获取不到先从注册中心刷新注册表再同步到本地缓存。Eureka Client 获取到目标服务器信息发起服务调用。Eureka Client 程序关闭时向 Eureka Server 发送取消请求Eureka Server 将实例从注册表中删除。通过分析 Eureka 工作原理我可以明显地感觉到 Eureka 的设计之巧妙完美地解决了注册中心的稳定性和高可用性。Eureka 为了保障注册中心的高可用性容忍了数据的非强一致性服务节点间的数据可能不一致 Client-Server 间的数据可能不一致。比较适合跨越多机房、对注册中心服务可用性要求较高的使用场景。| NacosNacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。Nacos 主要特点如下服务发现和服务健康监测Nacos 支持基于 DNS 和基于 RPC 的服务发现。服务提供者使用原生SDK、OpenAPI、或一个独立的Agent TODO注册 Service 后服务消费者可以使用DNS TODO 或HTTPAPI查找和发现服务。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 是阿里开源的支持基于 DNS 和基于 RPC 的服务发现。Nacos 的注册中心支持 CP 也支持 AP对他来说只是一个命令的切换随你玩还支持各种注册中心迁移到 Nacos反正一句话只要你想要的他就有。Nacos 除了服务的注册发现之外还支持动态配置服务一句话概括就是 Nacos Spring Cloud注册中心 Spring Cloud 配置中心。| ConsulConsul 是 HashiCorp 公司推出的开源工具用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案Consul 的方案更“一站式”内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案不再需要依赖其它工具比如 ZooKeeper 等。Consul 使用起来也较为简单使用 Go 语言编写因此具有天然可移植性(支持Linux、windows和Mac OS X)安装包仅包含一个可执行文件方便部署与 Docker 等轻量级容器可无缝配合。Consul 的调用过程当 Producer 启动的时候会向 Consul 发送一个 post 请求告诉 Consul 自己的 IP 和 Port。Consul 接收到 Producer 的注册后每隔 10s默认会向 Producer 发送一个健康检查的请求检验 Producer 是否健康。当 Consumer 发送 GET 方式请求 /api/address 到 Producer 时会先从 Consul 中拿到一个存储服务 IP 和 Port 的临时表从表中拿到 Producer 的 IP 和 Port 后再发送 GET 方式请求 /api/address。该临时表每隔 10s 会更新只包含有通过了健康检查的 Producer。Consul 主要特征CP模型使用 Raft 算法来保证强一致性不保证可用性。支持服务注册与发现、健康检查、KV Store 功能。支持多数据中心可以避免单数据中心的单点故障而其部署则需要考虑网络延迟, 分片等情况等。支持安全服务通信Consul 可以为服务生成和分发 TLS 证书以建立相互的 TLS 连接。支持 http 和 dns 协议接口。官方提供 web 管理界面。多数据中心这里纯属了解学习一下 Consul 的多数据中心是如何实现的。Consul 支持开箱即用的多数据中心这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。在上图中有两个 DataCenter他们通过 Internet 互联同时请注意为了提高通信效率只有 Server 节点才加入跨数据中心的通信。在单个数据中心中Consul 分为 Client 和 Server 两种节点所有的节点也被称为AgentServer 节点保存数据Client 负责健康检查及转发数据请求到 Server。Server 节点有一个 Leader 和多个 FollowerLeader 节点会将数据同步到 FollowerServer 的数量推荐是 3 个或者 5 个在 Leader 挂掉的时候会启动选举机制产生一个新的 Leader。集群内的 Consul 节点通过 gossip 协议流言协议维护成员关系也就是说某个节点了解集群内现在还有哪些节点这些节点是 Client 还是 Server。单个数据中心的流言协议同时使用 TCP 和 UDP 通信并且都使用 8301 端口。跨数据中心的流言协议也同时使用 TCP 和 UDP 通信端口使用 8302。集群内数据的读写请求既可以直接发到 Server也可以通过 Client 使用 RPC 转发到 Server请求最终会到达 Leader 节点在允许数据延时的情况下读请求也可以在普通的 Server 节点完成集群内数据的读写和复制都是通过 TCP 的 8300 端口完成。| ETCDetcd 是一个 Go 言编写的分布式、高可用的一致性键值存储系统用于提供可靠的分布式键值存储、配置共享和服务发现等功能。ETCD 特点易使用基于 HTTPJSON 的 API 让你用 curl 就可以轻松使用易部署使用 Go 语言编写跨平台部署和维护简单强一致使用 Raft 算法充分保证了分布式系统数据的强一致性高可用具有容错能力假设集群有 n 个节点当有 (n-1)/2 节点发送故障依然能提供服务持久化数据更新后会通过 WAL 格式数据持久化到磁盘支持 Snapshot 快照快速每个实例每秒支持一千次写操作极限写性能可达 10K QPS安全可选 SSL 客户认证机制ETCD 3.0除了上述功能还支持 gRPC 通信、watch 机制ETCD 框架主要分为四个部分HTTP Server用于处理用户发送的 API 请求以及其他 etcd 节点的同步与心跳信息请求。Store用于处理 etcd 支持的各类功能的事务包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等是 etcd 对用户提供的大多数 API 功能的具体实现。RaftRaft 强一致性算法的具体实现是 etcd 的核心。WALWrite Ahead Log预写式日志是 etcd 的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外etcd 就通过 WAL 进行持久化存储。WAL 中所有的数据提交前都会事先记录日志。Snapshot 是为了防止数据过多而进行的状态快照Entry 表示存储的具体日志内容。通常一个用户的请求发送过来会经由 HTTP Server 转发给 Store 进行具体的事务处理如果涉及到节点的修改则交给 Raft 模块进行状态的变更、日志的记录然后再同步给别的 etcd 节点以确认数据提交最后进行数据的提交再次同步。注册中心对比选型| 注册中心对比如下图服务健康检查Euraka 使用时需要显式配置健康检查支持Zookeeper、Etcd 则在失去了和服务进程的连接情况下任务不健康而 Consul 相对更为详细点比如内存是否已使用了90%文件系统的空间是不是快不足了。多数据中心Consul 和 Nacos 都支持其他的产品则需要额外的开发工作来实现。KV 存储服务除了 Eureka其他几款都能够对外支持 k-v 的存储服务所以后面会讲到这几款产品追求高一致性的重要原因。而提供存储服务也能够较好的转化为动态配置服务哦。CAP 理论的取舍Eureka 是典型的 APNacos 可以配置为 AP作为分布式场景下的服务发现的产品较为合适服务发现场景的可用性优先级较高一致性并不是特别致命。而 Zookeeper、Etcd、Consul 则是 CP 类型牺牲可用性在服务发现场景并没太大优势。Watch 的支持Zookeeper 支持服务器端推送变化其它都通过长轮询的方式来实现变化的感知。自身集群的监控除了 Zookeeper 和 Nacos其它几款都默认支持 metrics运维者可以搜集并报警这些度量信息达到监控目的。Spring Cloud的集成目前都有相对应的 boot starter提供了集成能力。| 注册中心选型关于注册中心的对比和选型其实上面已经讲的非常清楚了我给出一些个人理解关于 CP 还是 AP 的选择选择 AP因为可用性高于一致性所以更倾向 Eureka 和 Nacos关于 Eureka、Nacos 如何选择哪个让我做的事少我就选择哪个显然 Nacos 帮我们做了更多的事。技术体系Etcd 和 Consul 都是 Go 开发的Eureka、Nacos、Zookeeper 和 Zookeeper 都是 Java 开发的可能项目属于不同的技术栈会偏向选择对应的技术体系。高可用这几款开源产品都已经考虑如何搭建高可用集群有些差别而已产品的活跃度这几款开源产品整体上都比较活跃。尽信书则不如无书因个人能力有限难免有疏漏和错误之处如发现bug或者有更好的建议欢迎批评指正不吝感激。