Nacos 的架构和工作原理是什么?
简化版
Nacos 是阿里开源的注册中心 + 配置中心二合一组件。作为注册中心,它支持两种实例类型:临时实例(默认,靠客户端心跳保活,走 AP 模式、用 Distro 协议)和持久实例(靠服务端主动健康检查,走 CP 模式、用 Raft 协议)。工作流程:服务提供者注册实例并定期发心跳(默认每 5 秒),Nacos 服务端超过一定时间没收到心跳就先标记不健康、再剔除;消费者通过订阅 + 服务端推送(UDP/长轮询)+ 本地缓存获取实例列表变化。Nacos 集群节点间通过 Distro/Raft 协议同步数据。
详细版
Nacos 核心特性:
- 注册中心 + 配置中心一体:一个组件解决服务发现和配置管理。
- 临时实例(Ephemeral,默认):客户端心跳保活,AP 模式(Distro 协议)。
- 持久实例(Persistent):服务端健康检查,CP 模式(Raft 协议)。
- 推拉结合:客户端订阅,服务端在实例变化时推送;客户端也定时拉取兜底;本地缓存保证可用性。
注册与保活流程:
1. Provider 注册实例(默认临时实例)到 Nacos
2. Provider 每 5 秒发一次心跳
3. Nacos 服务端:
- 15 秒未收到心跳 → 标记实例【不健康】(还在列表但不推荐)
- 30 秒未收到心跳 → 【剔除】实例
4. Consumer 订阅服务 → Nacos 推送实例变化 → Consumer 更新本地缓存
完整版教学
一、Nacos 的定位:注册 + 配置二合一
Nacos(Naming and Configuration Service)是阿里巴巴开源的动态服务发现、配置管理平台。它最大的特点是一个组件同时承担了「注册中心」和「配置中心」两个角色——用一套系统既能做服务注册发现,又能做统一配置管理,减少了组件数量、降低了运维成本。这也是它相比 Eureka(只做注册)、Apollo(只做配置)的优势之一。本题聚焦它作为注册中心的原理。
二、两种实例类型:临时 vs 持久
Nacos 注册的实例分两种,这是理解它 AP/CP 的关键:
① 临时实例(Ephemeral,默认):
- 靠客户端主动发心跳给 Nacos 服务端来保活。
- 心跳超时,服务端认为实例挂了,剔除它。
- 走 AP 模式,用阿里自研的 Distro 协议做集群数据同步。
- 适合大多数微服务场景(服务实例频繁上下线,要高可用)。
② 持久实例(Persistent):
- 注册后一直存在,即使实例宕机也不会被自动删除(只是标记为不健康)。
- 由服务端主动做健康检查(主动去探测实例)。
- 走 CP 模式,用 Raft 协议保证强一致。
- 适合需要强一致、或需要持久记录的场景(如一些基础设施类服务)。
通过实例的 ephemeral 属性(true/false)选择类型。默认是临时实例 + AP,这也是服务发现推荐的模式。
三、心跳保活机制(临时实例)
临时实例的健康维持靠客户端心跳:
- 提供者注册实例后,每隔 5 秒(默认)向 Nacos 发送一次心跳,表明「我还活着」。
- Nacos 服务端维护每个实例的最后心跳时间。
- 如果超过 15 秒没收到某实例的心跳,Nacos 把它标记为不健康(unhealthy)——此时实例还在列表里,但不会被推荐给消费者。
- 如果超过 30 秒还没心跳,Nacos 直接剔除该实例。
这个「15 秒标记不健康、30 秒剔除」的两段式设计,比「一超时就删」更稳健——短暂的网络抖动导致的心跳丢失,先标记不健康而非立即删除,给实例恢复的机会。
四、服务发现:推拉结合 + 本地缓存
消费者获取和更新服务列表用推拉结合:
- 订阅 + 推送(Push):消费者订阅关心的服务。当服务的实例列表发生变化(上线/下线/健康状态变),Nacos 服务端主动推送变更给订阅的消费者(早期用 UDP 推送,新版用长连接)。这样变化能及时通知。
- 定时拉取(Pull)兜底:消费者也会定时(默认每 10 秒)主动拉取一次最新列表,作为推送丢失的兜底,保证最终一致。
- 本地缓存:消费者把拉到的服务列表缓存在本地。这样即使 Nacos 服务端暂时挂了,消费者仍能用本地缓存的地址继续调用服务,不至于立刻瘫痪(保证可用性,见「注册中心宕机」专题)。
五、集群与数据同步
Nacos 集群部署时,多个 Nacos 节点之间要同步注册数据:
- AP 模式(临时实例)用 Distro 协议:这是阿里自研的最终一致性协议。每个 Nacos 节点负责一部分实例数据(分片),节点间异步复制。保证高可用,允许短暂不一致。
- CP 模式(持久实例)用 Raft 协议:强一致性协议,写请求经 Leader 同步到多数节点才成功,保证各节点数据一致。
所以 Nacos 是AP、CP 两套协议并存——临时实例走 Distro(AP),持久实例走 Raft(CP),按实例类型自动选择。这正是它「AP/CP 可切换」的实现基础。
六、常见误区与追问
这道题面试时最容易丢分的地方,是把「Nacos 注册发现原理」答成一段泛泛的组件介绍。更稳的答法是先给结论,再沿着 服务注册与发现链路 拆清楚流程,最后补上异常场景、数字边界和选型取舍。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心定义 | Nacos 通过服务、集群、实例模型管理地址,临时实例偏 AP 心跳,持久实例偏 CP 一致性 | 不要停在名词解释 |
| 流程机制 | Provider 注册实例到 Nacos -> Nacos 保存服务实例模型 -> Consumer 订阅服务并缓存列表 -> Provider 发送心跳 -> 实例变化后通知 Consumer | 说明谁触发、谁存储、谁通知、谁兜底 |
| 工程取舍 | 服务 user-service 可挂 3 个实例,客户端订阅后本地缓存列表,实例变更时通过推送或拉取更新 | 注册信息不是业务数据,短暂不一致通常靠客户端缓存、重试和健康检查兜底 |
Nacos 注册发现原理 面试拆解:
1. Provider 注册实例到 Nacos
2. Nacos 保存服务实例模型
3. Consumer 订阅服务并缓存列表
4. Provider 发送心跳
5. 实例变化后通知 Consumer
记忆钩子:先区分注册、发现、心跳、剔除和本地缓存,再说明一致性与可用性的取舍;回答时一定要落到题目中的「Nacos 注册发现原理」,不要把相邻中间件的能力混着讲。
- 误区:Nacos 只是一个地址表。 它还包含命名空间、分组、集群、权重、健康状态、临时/持久实例等治理信息。
- 误区:所有 Nacos 实例都按同一种一致性协议处理。 临时实例和持久实例模型不同,一致性与健康检查策略也不同。
- 误区:消费者每次调用都查 Nacos。 实际会本地缓存服务列表,调用时走本地负载均衡,变更时再刷新。
- 追问:Nacos 如何发现实例下线? 临时实例主要靠心跳超时,持久实例可由服务端探测或人工维护状态。
- 追问:Nacos 为什么能同时做注册中心和配置中心? 两者都需要集中存储、变更通知和权限隔离,但管理对象分别是服务实例和配置数据。
- 追问:面试要不要讲 Distro/Raft? 可以点到临时实例偏 Distro/AP、持久数据偏 Raft/CP,但要围绕题目说明取舍。
七、加强记忆
Nacos = 阿里开源的注册中心 + 配置中心二合一。作为注册中心,支持两种实例:临时实例(默认)——客户端每 5 秒发心跳保活,15 秒无心跳标记不健康、30 秒剔除,走 AP(Distro 协议);持久实例——服务端主动健康检查,走 CP(Raft 协议),宕机不删只标记不健康。服务发现用推拉结合:订阅后服务端推送变更 + 定时拉取兜底 + 本地缓存(Nacos 挂了消费者仍能用缓存调用)。集群同步:**AP 用 Distro(最终一致)、CP 用 Raft(强一致)**并存。核心:临时实例+心跳+AP 是默认、二合一是特色、本地缓存保可用。