Nacos注册发现、配置与生产排查面试题
本页只保留标准回答、追问方向和精确原理跳转。第一次学习请先阅读Nacos基础和Nacos内部原理与生产治理。
1. Nacos是什么
标准回答: Nacos同时提供Naming和Config。Naming维护Namespace、Group、Service到Instance列表的映射,客户端订阅并缓存在本地,再由LoadBalancer选择真实地址;Config通过Namespace、Group、DataId定位配置,应用启动时拉取,运行期通过监听、MD5和刷新机制更新。Nacos不转发业务请求,也不能把Naming和Config用同一套一致性原理解释。
2. 一次Nacos服务注册怎样走
标准回答: Nacos 2.x客户端由NacosNamingService构造Instance,NamingClientProxyDelegate选择协议,临时实例通常由NamingGrpcClientProxy缓存期望注册状态并发送InstanceRequest。Server根据connectionId找到连接型Client,把Service和Instance关联,更新revision并发布注册事件,随后用Distro把临时数据同步到其他节点。
原理:临时实例注册链
3. Nacos 1.x和2.x通信有什么区别
标准回答: 1.x常见Naming HTTP注册查询、UDP推送和客户端Beat,Config使用HTTP长轮询;2.x主线使用gRPC长连接、Server推送、连接事件和注册订阅Redo,Config使用批量监听上下文与变更通知,但仍保留部分HTTP兼容接口。不能把1.x机制说成所有版本都一样。
原理:版本边界
4. 8848、9848、9849和7848分别是什么
标准回答: 默认8848是控制台、OpenAPI和兼容HTTP端口;9848是8848加1000,用于SDK客户端gRPC;9849是加1001,用于Server间gRPC;7848是减1000,常用于JRaft/CP协议。客户端通常仍配置8848并由SDK计算偏移。只放通8848会出现控制台正常但2.x客户端注册监听失败。
原理:端口模型
5. 临时实例和持久实例有什么区别
标准回答: 临时实例生命周期依赖客户端会话,1.x常见Beat,2.x原生客户端主要依赖gRPC连接和连接事件,失联后清理;持久实例不因连接断开删除,变更经JRaft多数派提交,Server可用TCP、HTTP、MySQL等主动探测并标记健康状态。持久不等于永远健康。
6. 消费者每次Feign调用都会访问Nacos吗
标准回答: 不会。消费者订阅Service后把ServiceInfo保存在本地,实例变化由Server推送并更新缓存。Feign调用时,Spring Cloud LoadBalancer从本地实例列表取候选并选择地址,再由HTTP客户端调用。Nacos短暂不可用时旧缓存仍可能工作,但也会产生调用已下线实例的陈旧窗口。
7. Nacos提供实例后是谁做负载均衡
标准回答: 直接调用Nacos selectOneHealthyInstance时,Nacos客户端可以做权重选择;Spring Cloud OpenFeign或Gateway主链中,Nacos Discovery主要提供实例列表,Spring Cloud LoadBalancer及扩展策略做最终选择。还会经过Cluster、Healthy、Enabled、Weight、metadata和Zone等过滤。
原理:负载均衡边界
8. Nacos Server挂了,服务之间还能调用吗
标准回答: 可能暂时能。消费者通常使用本地ServiceInfo,已有实例之间可继续调用;但新实例无法发现、下线实例可能继续被调用、提供者重连和订阅推送受影响。能撑多久取决于缓存、旧实例存活、HTTP连接和超时治理,不能回答成“完全不影响”。
原理:本地缓存与旧实例窗口、失败窗口
9. Nacos 2.x连接重建后为什么要Redo
标准回答: 注册和订阅绑定客户端连接。切到新Server后,新连接不知道旧连接期望注册和订阅什么。NamingGrpcRedoService缓存期望状态,断线时标记未注册,重连后定时重新注册实例和订阅Service。连接恢复到Redo完成之间仍有短暂窗口。
原理:Redo恢复
10. Distro是什么
标准回答: Distro主要用于临时Naming数据。连接所在节点负责该Client,变更后生成DistroKey并通过延迟任务同步到其他节点,节点启动和运行期还有快照加载、Verify和差异修复。它优先可用性和最终收敛,不要求每次注册等待多数派,所以分区时节点实例视图可能短暂不同。
原理:Distro临时数据同步
11. Nacos哪里使用JRaft
标准回答: Nacos 2.x持久Naming实例等CP数据通过CPProtocol/JRaft处理。写请求由Leader追加日志、复制到Follower、多数派确认后提交,再由状态机onApply,并通过快照恢复。失去多数派时不能继续承诺持久写成功。
原理:JRaft链路
12. Nacos到底是AP还是CP
标准回答: 不能给整个Nacos贴一个标签。临时Naming实例走Distro,偏AP和最终一致;持久Naming实例走JRaft,偏CP;Config以数据库持久化、Server缓存通知和客户端Snapshot为独立链路。回答时必须先问是哪类数据和哪条操作。
原理:AP与CP边界
12.1 Nacos为什么可能返回不健康实例
标准回答: 这通常和保护阈值、空列表保护、本地缓存和连接池窗口有关。注册中心发现大量实例不健康时,可能为了避免误摘除导致全站无实例而触发保护,返回更宽的候选集合;客户端收到异常空推送时也可能保留最后一次可用快照。它保护的是可用性,不保证每个实例都健康,所以调用端仍要短超时、熔断、慢实例降权、连接池回收和幂等补偿。
原理:保护阈值与空列表保护
12.2 空列表保护是不是一定要开启
标准回答: 不能一概而论。空列表保护能避免Nacos异常推空、网络分区或版本问题导致所有消费者瞬间无实例,但如果服务确实全部下线,它会延长调用旧实例的窗口。生产要结合业务风险、服务下线流程、LB缓存TTL、连接池回收、错误率告警和灰度策略决定,不能用它掩盖Namespace、Group或灰度规则错误。
原理:空列表保护边界
13. Nacos Config启动读取顺序是什么
标准回答: NacosConfigService按Namespace、Group、DataId定位配置,源码中先检查显式本地Failover文件;没有Failover时请求Server,成功后保存Snapshot;Server请求失败时可回退最近Snapshot,最后交给Spring Environment。Snapshot可能过旧,关键配置应fail-fast或校验最低版本。
原理:配置启动拉取
14. Nacos 2.x配置动态刷新怎样工作
标准回答: ClientWorker为每个监听项维护CacheData、内容和MD5,批量把监听上下文发给Server。Server发现变化后推送DataId、Group、Tenant标识,客户端将缓存标为不一致,重新查询完整内容,更新Content和MD5,再回调MD5发生变化的Listener。之后Spring是否刷新还取决于PropertySource和Bean生命周期。
原理:Config监听链、Listener与Spring刷新
15. 配置变更通知丢失会永远不刷新吗
标准回答: 通常不会永久丢失。2.x客户端连接重建会重同步监听上下文,批量MD5比较和周期全量同步能发现不一致;但会产生刷新延迟。仍要监控配置版本收敛,不能把补偿机制理解为所有实例瞬间一致。
原理:Config监听补偿
16. Failover文件和Snapshot有什么区别
标准回答: Failover文件是显式本地接管,存在时可优先使用;Snapshot是最近一次成功拉取配置的本地副本,Server失败时用于降级。两者都可能过旧,且可能包含敏感配置。不能把Snapshot当作最新事实,也不能不经评估就让写服务用旧配置启动。
原理:配置启动与本地降级
17. 为什么Nacos控制台改了配置,Bean仍是旧值
标准回答: 要逐层确认:Server是否持久化,客户端是否收到通知并重新拉取,Environment是否更新,属性绑定是否重新执行,Bean是否支持刷新,复杂资源是否完成安全切换。构造器只读一次的普通对象不会因Environment变化自动重建,数据源、MQ和线程池也不应简单热刷新。
18. 配置发布接口返回成功是否代表全实例生效
标准回答: 不代表。成功通常只证明Server接受并持久化发布;Server缓存、客户端通知、重新拉取、Listener排队、Environment更新和Bean切换还有传播窗口。生产要给配置加版本,并按实例验证收敛、指标和回滚状态。
原理:配置发布链、Config一致性窗口
19. Namespace、Group、Service、Cluster和DataId怎样区分
标准回答: Namespace做环境或租户级逻辑隔离;Group对服务或配置继续分组;Service是注册发现的服务名;Cluster是实例的机房或区域分组;DataId是配置标识。Naming常按Namespace、Group、Service、Cluster定位,Config按Namespace、Group、DataId定位。Namespace显示名不一定等于客户端使用的ID。
原理:基础模型
20. 为什么控制台正常,Nacos客户端却连不上
标准回答: 控制台主要验证8848 HTTP,Nacos 2.x客户端还需要9848 gRPC。常见原因是SLB、Ingress、防火墙只开放8848,gRPC协议或长连接超时配置错误,Server上报地址不可达,或客户端与Server版本能力不兼容。要分别测试8848和9848,查看remote连接日志。
21. 实例已下线,为什么还会有请求打过去
标准回答: 下线信息需要经过Server注册表、订阅推送、消费者ServiceInfo、LoadBalancer缓存和HTTP连接池传播;线程中已取得的旧快照和在途请求也不会被撤销。应先摘流量、等待传播和连接排空,再停进程,并配置短连接超时、有限重试和熔断。
22. No servers available怎样排查
标准回答: 先保存调用方异常和本地ServiceInfo,再按Service名、Namespace ID、Group、Cluster核对Server注册表;检查9848连接、订阅和Redo;确认实例Healthy、Enabled、Weight和metadata;最后验证注册IP从消费者可达以及LoadBalancer过滤。只重启消费者会掩盖根因。
原理:服务发现Runbook
23. 为什么配置只在部分实例生效
标准回答: 可能是客户端连接和监听状态不同、实例使用不同DataId/Group/Namespace、部分实例命中旧Snapshot、Listener回调失败、类型转换失败、Bean不支持刷新或发布版本不一致。应暴露无敏感的生效版本并按实例聚合,而不是只看控制台值。
24. Nacos和Eureka有什么区别
标准回答: Eureka主要是Spring Cloud Netflix历史注册中心,强调客户端缓存和可用性;Nacos同时提供Naming和Config,并有Namespace、Group、Cluster、临时/持久实例、Distro和JRaft等能力。不能只说“Nacos功能更多”,还要考虑端口、数据库、权限、配置发布和更重的平台运维职责。
25. Nacos生产高可用要注意什么
标准回答: 使用多节点和高可用配置数据库,规划8848、9848、9849、7848网络,监控gRPC连接、Redo、ServiceInfo年龄、Distro差异、Raft Leader和Config通知;控制台内网隔离并启用鉴权;Server和Client按兼容矩阵灰度升级;定期备份并演练数据库、Raft多数派和配置回滚。
