找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3062

积分

0

好友

457

主题
发表于 3 天前 | 查看: 17| 回复: 0

做 Spring Cloud 开发的同学,对 Nacos 肯定不陌生。配置文件里配好 Nacos 地址,服务启动后就会自动注册上去。但你是否注意到一个细节:当服务进程被停掉或 kill 掉之后,Nacos 控制台上的服务实例会很快消失,而不是变成红色的不健康状态。这与早期使用 Zookeeper 或 Dubbo 时,节点信息会保留的情况不太一样。

为什么 Nacos 默认选择直接删除掉下线的实例呢?

临时 vs 持久

在 Nacos 的设计中,服务实例分为两种类型:临时实例(Ephemeral)持久实例(Persistent)。Spring Cloud Alibaba 默认采用的配置就是临时实例

两者的核心区别在于心跳维持机制实例下线后的处理方式

临时实例(默认)

  • 心跳机制:由客户端(即你的微服务)主动向 Nacos Server 发送心跳,默认间隔为5秒。
  • 下线处理:如果 Nacos Server 在预设的时间窗口内(例如30秒)未收到心跳,则判定该实例已下线,并直接从服务列表中剔除

持久实例

  • 心跳机制:客户端仅在注册时通知 Nacos Server,之后不再主动发送心跳。由 Nacos Server 端主动探测该实例的IP端口是否可达。
  • 下线处理:如果探测失败,Nacos Server 只会将该实例标记为“不健康”,但不会删除其注册信息。这条记录会一直保留在服务列表中。

为什么要默认选临时?

可能有些从传统架构转型过来的开发者会疑惑:保留历史记录不是更方便排查问题吗?在物理机或固定IP的时代,这确实是个好思路。机器重启后,IP不变,记录仍有价值。

然而,随着 Docker 和 K8s 的普及,环境发生了根本性变化。想象一下你的服务部署在 Kubernetes 中的场景:

  1. 每次应用发布或滚动更新,旧的 Pod 会被销毁,新的 Pod 被创建。
  2. 关键点在于:新 Pod 的 IP 地址通常是全新的。

如果你为这些动态的微服务应用配置了持久实例,那么每次发布后,Nacos 中就会残留一堆标记为“不健康”的旧 IP。频繁发布几次,服务列表里就可能堆积成百上千个无效地址。这不仅浪费存储空间,更严重的是,当其他服务客户端拉取服务列表时,还需要额外花费资源去过滤这些早已不存在的死节点。

因此,Nacos 默认选择临时实例,正是为了适应云原生环境下“IP 是临时资源”的现实。服务实例下线即清理,为新实例腾出位置,始终保持服务列表的简洁与有效。

深层原因:CAP 的取舍

除了应对IP动态变化,还有一个更底层的架构原因涉及分布式系统的 CAP 理论

持久实例(CP 模式)

为了实现数据的强一致性和持久化,持久实例在 Nacos 集群内部通常采用 Raft 协议 进行数据同步。Raft 是强一致性协议,这意味着如果集群中的 Leader 节点发生故障,在选举出新 Leader 期间,整个注册中心将处于不可写状态。对于需要频繁注册、下线的微服务应用而言,因网络抖动或短暂故障就导致服务无法注册,这是难以接受的。

临时实例(AP 模式)

临时实例则采用 Nacos 自研的 Distro 协议。它的设计哲学是:高可用性(Availability)优先于强一致性(Consistency)。即使集群内节点间的数据未能实时完全同步,也要确保服务能够成功注册和被发现,保证整个调用链路的基本可用,不因注册中心的内部状态而报错。

什么时候该用持久实例?

那么,持久实例就一无是处了吗?并非如此。它主要适用于那些 IP 地址相对固定、且属于关键基础设施 的服务,例如数据库(MySQL、Redis)。

有时,我们希望将数据库地址也注册到 Nacos 中,供微服务动态发现。对于数据库这类“重资产”,即使它暂时不可用,我们也不希望其注册信息从列表中消失。我们更期待它仅被标记为异常,待故障修复后,同样的 IP 和端口能自动恢复服务,业务无需修改配置。

总结

回到最初的问题:Nacos 服务注册为什么默认是临时实例?

核心原因在于,在现代微服务与云原生架构下,服务的可用性比记住所有历史状态更重要

  • 对于微服务应用:它们是动态的、可随时调度和销毁的资源,应使用临时实例(AP 模式)。实例下线即刻清理,确保服务列表的实时有效性,避免客户端调用到无效节点。
  • 对于数据库/基础设施:它们是相对固定的、重要的资源,可以考虑使用持久实例(CP 模式)。保留其注册记录,便于运维监控与故障恢复。

因此,在 Kubernetes 等动态环境中使用 Nacos 时,建议保持默认的临时实例配置。若误开启持久化模式,控制台可能会逐渐堆积大量无法自动清理的无效数据,反而影响服务发现效率。希望这个设计背后的思考,能帮助你在使用类似注册中心时做出更合适的选择。关于微服务架构的更多实践与原理,欢迎在云栈社区交流讨论。




上一篇:线程池异常静默消失?探究控制台不打日志的背后原因
下一篇:Redis分布式锁失效分析:JVM STW导致的时间差问题
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-10 12:16 , Processed in 0.550857 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表