服务注册与发现:Eureka、Consul、Nacos 三强争霸
各位好,我是这个系列课程的主讲。今天咱们来聊聊微服务架构里最基础,也是面试最常被问到的一个环节——服务注册与发现。
说白了,当你的系统从单体拆成几十甚至上百个微服务之后,一个服务怎么找到另一个服务?总不能还靠手写 IP 和端口吧?那就回到了石器时代。
这时候就需要一个“电话本”——注册中心。每个服务启动时,把自己的地址(IP +端口)登记上去。调用方去注册中心查一下,就能拿到目标服务的地址列表,直接发起远程调用。这个机制就是服务注册与发现。
目前业内主流的方案有三家:Eureka(Netflix 的)、Consul(HashiCorp 的)、Nacos(阿里的)。很多面试官会问:“你用过哪个?”“它们有什么区别?”“生产环境怎么选?”
今天我就以自己的项目经验,帮你把这三个家伙的原理、优缺点,以及面试考点一次讲透。
核心流程——它们是怎么工作的?
先别急着对比细节。你得先理解它们共有的核心流程。无论用哪一个,套路都差不多:
- 服务注册:服务实例启动后,向注册中心发送注册请求,携带自己的服务名、IP、端口、健康检查 URL 等信息。
- 服务心跳:实例定期向注册中心发送心跳(比如每 30 秒一次),告诉它“我还活着”。
- 健康检查:注册中心如果一段时间没收到心跳,就标记该实例为不健康,甚至直接剔除。
- 服务发现:调用方从注册中心获取目标服务的实例列表,缓存在本地,然后按负载均衡策略选一个发起调用。
- 服务变更通知:当实例列表发生变化(新增、下线、故障),注册中心要能通知到调用方。
嗯,基本原理就是这个。但具体实现上,Eureka、Consul、Nacos 各有各的风格。
Eureka——经典配置,AP 主义的坚守者
Eureka 是 Netflix 开源的组件,也是 Spring Cloud 早期版本默认使用的注册中心。我当年入坑微服务时,用的就是 Eureka。
它的最大特点:AP 原则(可用性 + 分区容错性)。
什么意思?就是在网络发生分区(比如机房断网)时,Eureka 优先保证服务仍然可用,哪怕数据可能不一致。每个 Eureka 节点都是平等的,只要有一台存活,就能保证注册服务可用。
Eureka 的局限也很明显:没有内置的配置管理功能,健康检查比较简单(只支持客户端心跳),且不提供一致性的强保证。如果你想用 Eureka + 配置中心,还得额外搭一个 Spring Cloud Config。
配置示例(经典的 Spring Cloud 集成):
# application.yml(Eureka 服务端)
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
客户端注册也很简单,引入依赖后加注解就行。
Consul——强一致,功能更全的“全能选手”
Consul 是 HashiCorp 公司的产品,它和 Eureka 最大的不同:CP 原则(一致性 + 分区容错性)。
它使用 Raft 算法保证数据强一致。这就意味着,如果网络发生分区,Consul 可能会牺牲一部分可用性,等分区恢复后,数据才完全一致。这在某些对数据一致性要求极高的场景下是必须的。
除了服务注册与发现,Consul 还自带:
- 健康检查:支持多种方式(HTTP、TCP、Shell 脚本),比 Eureka 的心跳更灵活。
- K-V 存储:可以当配置中心用,但功能不如 Nacos 或 Apollo 完善。
- 多数据中心:天生支持跨机房、跨地域的部署。
我个人习惯在需要强一致性和跨数据中心部署的场景下推荐 Consul。不过 Consul 的运维成本比 Eureka 稍高,因为它依赖 Agent 进程。
注册配置示例:
# 注册一个名为 "order-service" 的实例
curl -X PUT -d '{
"ID": "order-service-1",
"Name": "order-service",
"Address": "192.168.1.10",
"Port": 8080,
"Check": {
"HTTP": "http://192.168.1.10:8080/health",
"Interval": "10s"
}
}' http://localhost:8500/v1/agent/service/register
Nacos——动态切换,阿里生态的集大成者
Nacos 是阿里巴巴开源的产品,全称是“动态命名和配置服务”。它最大的亮点是:既支持 AP 模式,也支持 CP 模式,可以动态切换。
你用 Nacos 做个内部服务发现,可以选择 AP 模式(临时实例),追求高可用。如果你用它来做关键配置分发,或者需要强一致性的服务发现,可以切到 CP 模式(持久化实例,使用 Raft 保证一致性)。
我建议你记住这个亮点,面试时非常能加分。因为很多人只知道 Eureka 是 AP,Consul 是 CP,但 Nacos 可以根据场景自由选择。
Nacos 另一个杀器是:它把注册中心和配置中心合二为一。以往我们要搭 Eureka + Spring Cloud Config,或者 Consul + 第三方配置工具,但 Nacos 一个包就搞定一切。运维成本大幅降低。
Nacos 的配置示例(Spring Cloud Alibaba 集成):
# application.yml
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
namespace: dev
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
三强对比——一张表帮你理清
面试官最喜欢问的就是对比。我帮你整理成表格,你直接背下来就行。
| 对比维度 | Eureka | Consul | Nacos |
|---|---|---|---|
| 一致性模型 | AP(最终一致) | CP(强一致,Raft) | AP/CP 动态切换 |
| 健康检查 | 客户端心跳(比较弱) | 多种方式(HTTP/TCP/脚本) | 心跳 + HTTP/TCP 可选 |
| 配置管理 | 不支持(需额外组件) | 支持 K-V,但功能有限 | 原生支持,功能强大 |
| 多数据中心 | 不原生支持 | 原生支持 | 支持(通过命名空间等) |
| 社区生态 | Spring Cloud 早期王者,已停更 | HashiCorp 生态,持续更新 | Spring Cloud Alibaba,活跃 |
| 运维复杂度 | 低(无依赖) | 中(依赖 Agent) | 中(自带控制台) |
| 推/拉模式 | 拉(Client 定时拉取) | 事件推送 + 长轮询 | 推 + 拉(UDP 推送) |
| 实例类型 | 临时实例(默认) | 临时 + 持久化 | 临时 + 持久化 |
- 一致性模型影响什么? 如果你的业务允许短暂的不一致(比如读取刚下线几秒的服务),可以用 AP。如果要求强一致(比如金融交易),用 CP。
- 健康检查有多重要? 非常重要。Eureka 单纯靠心跳,一旦网络拥堵,可能误杀正常服务。Consul 和 Nacos 支持 HTTP 检查,能更真实地反映服务状态。
- 配置管理:如果你不想再引入一个配置中心,Nacos 是最优选。Consul 的 K-V 能凑合用,但功能不够。Eureka 完全没有。
面试答题思路——怎么回答才显专业?
如果面试官问你:“你们项目为什么选 Nacos 而不是 Eureka?”
你别说“因为大家都用”。你可以这样组织回答:
- 先说选择依据:我们的业务对数据一致性要求不是特别强,但要求高可用,所以 Nacos 的 AP 模式很适合。另外我们需要配置中心,不想多维护一套系统,Nacos 天然支持。
- 再说对比优势:Eureka 虽然稳定,但已经基本停更了,而且健康检查太单一。Consul 虽然好,但我们团队对 Go 体系的运维不太熟悉,Nacos 基于 Java,和 Spring Cloud Alibaba 无缝集成。
- 最后来个总结:简单说,Nacos 解决了我们“注册 + 配置”两个痛点,运维成本最低,所以我们选它。
这样回答,有理有据,还体现了你的思考和项目经验。
好了,这就是服务注册与发现的面试精讲。下一部分,我们会聊聊这些组件在真实线上环境的落地经验——比如高并发下的服务发现延迟、如何保证注册中心自身的高可用等等。希望今天的内容对你有所帮助。