{T}

如何实现服务注册与发现?

0. 引言

微服务实例数量动态变化(扩缩容、故障、发布),调用方不能写死 IP。服务注册与发现解决"调用方如何实时找到可用实例":服务启动时向注册中心登记自己的地址,调用方从注册中心获取实例列表并做负载均衡。本文讲解注册中心的角色、核心机制与主流产品选型。

1. 注册中心的三个角色

图表渲染中…
角色行为
Provider(提供者)启动时注册(IP:Port + 元数据),下线时注销;持续发送心跳续约
Registry(注册中心)存储服务名 → 实例列表;检测实例存活(心跳超时剔除);推送变更
Consumer(消费者)启动时拉取并缓存实例列表;监听变更;本地负载均衡选实例

关键设计:消费者本地缓存实例列表 + 注册中心变更推送(或定时拉取)——即使注册中心短暂不可用,消费者仍能基于缓存继续调用(可用性兜底)。

2. 核心机制

2.1 注册与心跳

text
Provider 启动 → registry.register(serviceName, {ip, port, weight})
Provider 每 30s 心跳续约 → registry 记录 lastHeartbeat
Registry 检测:超过 90s 无心跳 → 标记不健康 → 剔除并通知
  • 心跳频率与剔除阈值:Eureka 默认 30s 心跳 / 90s 剔除;Nacos 临时实例 5s 心跳 / 15s 剔除;
  • 自我保护机制(Eureka):短时间内大量实例心跳失败时,不剔除(宁可保留可能已死的实例,也不误杀——因为大批量失败通常是网络分区而非实例故障)。

2.2 拉取与订阅

  • 拉模式:Consumer 定时拉取全量列表(Eureka 默认 30s,有延迟);
  • 推模式:注册中心变更时主动推送(Nacos 长轮询 1s 内感知、ZooKeeper Watch 即时通知);
  • 实践中常拉 + 推结合:初始拉全量 + 后续增量推送。

2.3 健康检查

注册中心检查方式说明
Eureka客户端心跳只看"进程活着",不探活业务
ZooKeeper会话超时临时节点随会话消失
Nacos心跳(临时)/ 主动探活(持久)持久实例由服务端 TCP 探活
Consul主动探活(HTTP/gRPC)服务端检查,最可靠

3. 主流注册中心对比

产品一致性健康检查语言特点
EurekaAP(最终一致)心跳JavaSpring Cloud Netflix 传统方案;已停止维护(2.x 夭折)
ZooKeeperCP(强一致)会话多语言临时节点天然支持;性能一般,写扩展性差
NacosAP/CP 可切换心跳/探活Java/Go阿里开源,支持临时+持久实例、配置中心二合一
ConsulCP(Raft)主动探活Go多数据中心、Service Mesh 支持好

Nacos 的 AP/CP 模式:临时实例(默认,AP)——心跳续约、服务端不持久化,健康检查快;持久实例(CP)——走 Raft 持久化 + 主动探活,适合服务端存储场景。选型口诀:注册发现选 AP(可用性优先),配置/选主选 CP。

4. 选型建议

text
Spring Cloud 老项目(Netflix 栈) → Eureka(存量维护)或迁移 Nacos
新 Java 项目 → Nacos(AP 注册 + CP 配置,功能最全)
已有 ZooKeeper 基础设施 → ZK(注意:注册场景建议用临时节点 + 会话)
云原生 / 多数据中心 → Consul

注意:ZooKeeper 做注册中心的隐患——ZK 是 CP 系统,分区时服务不可写,且写放大(每个实例注册都是写事务);Nacos 的 AP 模式正是为注册场景(读多写少、可用性优先)而设计。

5. 面试高频问题

  1. 注册中心选 CP 还是 AP? 注册发现是"读多写少、可用性 > 严格一致"场景 → AP 更合适(Eureka/Nacos 临时实例);但服务上下线状态不能长期不一致,所以需要最终一致 + 快速收敛;
  2. Eureka 和 Nacos 的区别? 一致性模型(AP vs AP/CP 可切换)、健康检查(心跳 vs 心跳+探活)、功能(Nacos 兼配置中心)、维护状态(Eureka 停更);
  3. 服务下线怎么通知消费者? 优雅下线:注销 → 等待(约 2 个心跳周期)→ 停机;注册中心推送变更 → 消费者更新本地缓存;
  4. 注册中心自己挂了怎么办? 消费者本地缓存兜底 + 多机房部署 + 注册中心集群(多数派)。

6. 小结

  • 注册中心三角色:Provider 注册、Registry 存储与检查、Consumer 拉取订阅
  • 核心机制:心跳续约、超时剔除、变更推送、本地缓存
  • 选型:新项目首选 Nacos(AP 注册 + 配置中心);云原生用 Consul;ZK 适合协调场景而非注册;
  • 注册中心挂掉 ≠ 服务不可用:消费者缓存 + 优雅下线是兜底双保险。

下一章讲解分布式调用跟踪:TraceID 传播、采样与 Zipkin/Jaeger 的链路还原。