Nacos 如何实现服务注册与发现?服务下线后为什么还可能收到请求?
以下对话为教学模拟,不是真实面经。
🧑💻 面试官:Nacos 怎样实现服务注册和发现?
🙋♂️ 我:服务注册到 Nacos,调用方查到地址再请求。
🧑💻 面试官:一个实例下线以后,为什么日志里还看到请求?是不是 Nacos 没更新?
🙋♂️ 我:调用方可能还在使用旧列表。
🧑💻 面试官:已经建立的连接和正在进行的请求,又由谁处理?
服务列表变化、调用方停止选择和实例完成退出,是三个不同阶段。
面试速答(60 秒版)
服务实例向 Nacos 注册地址和相关信息,调用方通过查询或订阅获得可用实例列表,再由客户端或负载均衡组件选择目标地址。
实例下线以后,注册中心更新不等于所有调用方立即停止请求。列表通知和本地缓存可能存在传播时间,已选择的请求和已有连接也可能继续运行。
因此,优雅下线要配合停止接收新流量、传播等待、连接排空和在途请求处理。不能只删除注册信息就立刻结束进程。
排查时我会分别检查 Nacos 中的实例状态、调用方实际使用的列表,以及请求是在下线前还是下线后选择目标,避免把所有残余请求都归因于注册中心。

知识点详解:从实例登记,到调用方真正不用它
注册中心提供地址,不代替所有业务请求
咱们假设 order-service 有三个实例。每个实例向注册中心报告自身信息;调用方获得列表以后,选择其中一个地址访问。
一般服务发现模式下,业务请求不会因此全部经过 Nacos 转发。Nacos 负责注册与发现,实际负载均衡和连接由调用链中的相应组件承担。
Nacos 的服务管理概览说明了服务、实例与相关管理能力。命名空间、分组和集群等配置也会影响调用方看到哪份列表,排查时必须确认查询的是同一个范围。
发现不是每个请求都重新读一遍中心
调用方可以订阅变化,并维护本地信息。这样减少中心查询成本,也让部分请求不必每次依赖注册中心实时响应。
代价是状态传播存在过程。实例状态已经变化,某个调用方可能还没有应用更新,或者它使用的缓存、适配器和负载均衡器仍然保留旧结果。
服务订阅与运维说明可以用于核对实际版本的管理方式。不能脱离客户端版本、实例类型和配置,承诺所有场景都有同样的“几秒心跳、几秒剔除”。
在途请求,不会因为名单删除自动消失
假设请求在实例下线之前已经选择了该地址,即使名单随后更新,这个请求也可能继续完成。
长连接、连接池和应用自身的地址缓存,又会增加不同边界。所以日志时间在“下线以后”,不一定表示请求目标也在下线以后才被选择。
要判断是不是异常,至少需要实例下线时间、通知应用时间、请求开始时间以及连接信息。只有一张注册中心截图,通常不够。

优雅下线,要让退出过程逐步完成
一个常见思路是:先降低或停止新流量进入,等待服务发现与其他入口传播变化,再处理在途请求和连接,最后终止进程。
具体顺序需结合网关、负载均衡、健康检查和服务实现验证。某些系统通过摘除或禁用实例处理,某些结合就绪检查;不能把一种平台配置当成通用命令。
重要的是保留安全退出窗口,同时设置最长等待。无限等在途请求,会让部署无法完成;立刻结束,又可能导致请求中断。
怎样定位残余请求来自哪里
可以按三个层次检查:
| 层次 | 要确认的事实 |
|---|---|
| 注册中心 | 实例是否已禁用、删除或被判定不可用 |
| 调用方 | 何时收到更新,实际列表与选择策略是什么 |
| 实例与连接 | 是否是旧连接、在途请求或其他入口流量 |
还要检查是否存在绕过服务发现的固定地址调用。这个请求路径与 Nacos 列表无关,中心更新再快也不会改变它。
验证时应使用多调用方和不同连接条件,记录传播与排空时间;不能只用单个客户端测试一次,然后推导整个系统能够无损下线。
面试官继续追问
注册中心不可用,服务一定马上不可调用吗?
不一定。客户端可能有本地列表,已有连接也可能继续工作。但更新、注册和恢复能力会受影响,实际行为需按客户端配置核对。
服务发现是不是负载均衡?
它提供候选地址,负载均衡决定选哪个。两者可以集成,但职责不同。
下线后仍有请求一定是 bug 吗?
不是。在途请求和传播窗口可能正常。应先按时间与路径区分,再判断是否超出设计预期。
面试速记卡
- 注册:实例报告地址与相关状态。
- 发现:调用方获得列表,再由相应组件选择地址。
- 传播边界:中心更新不等于所有客户端立即应用。
- 退出边界:旧连接与在途请求需要排空。
- 排查方法:中心、调用方、实例三层证据一起看。
公司面试真题
真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。
美团 · 后端(榛果民宿) · 原帖未明确批次
Nacos 注册中心有哪些使用场景,与其他注册中心有何差异?(题意整理)
美团offer call还愿 ↗
历史面经;原帖编辑于 2019-09-18