如何实现服务注册与发现?
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. 主流注册中心对比
| 产品 | 一致性 | 健康检查 | 语言 | 特点 |
|---|---|---|---|---|
| Eureka | AP(最终一致) | 心跳 | Java | Spring Cloud Netflix 传统方案;已停止维护(2.x 夭折) |
| ZooKeeper | CP(强一致) | 会话 | 多语言 | 临时节点天然支持;性能一般,写扩展性差 |
| Nacos | AP/CP 可切换 | 心跳/探活 | Java/Go | 阿里开源,支持临时+持久实例、配置中心二合一 |
| Consul | CP(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. 面试高频问题
- 注册中心选 CP 还是 AP? 注册发现是"读多写少、可用性 > 严格一致"场景 → AP 更合适(Eureka/Nacos 临时实例);但服务上下线状态不能长期不一致,所以需要最终一致 + 快速收敛;
- Eureka 和 Nacos 的区别? 一致性模型(AP vs AP/CP 可切换)、健康检查(心跳 vs 心跳+探活)、功能(Nacos 兼配置中心)、维护状态(Eureka 停更);
- 服务下线怎么通知消费者? 优雅下线:注销 → 等待(约 2 个心跳周期)→ 停机;注册中心推送变更 → 消费者更新本地缓存;
- 注册中心自己挂了怎么办? 消费者本地缓存兜底 + 多机房部署 + 注册中心集群(多数派)。
6. 小结
- 注册中心三角色:Provider 注册、Registry 存储与检查、Consumer 拉取订阅;
- 核心机制:心跳续约、超时剔除、变更推送、本地缓存;
- 选型:新项目首选 Nacos(AP 注册 + 配置中心);云原生用 Consul;ZK 适合协调场景而非注册;
- 注册中心挂掉 ≠ 服务不可用:消费者缓存 + 优雅下线是兜底双保险。
下一章讲解分布式调用跟踪:TraceID 传播、采样与 Zipkin/Jaeger 的链路还原。