十万个why:Nacos 服务注册为什么默认是临时实例?
做 Spring Cloud 开发的同学对 Nacos 肯定不陌生。大家平常写代码配置文件里只要配好 Nacos 地址程序一启动服务就自动注册上去了。但不知道大家有没有留意过一个细节当你把服务停掉或者直接 Kill 进程Nacos 控制台上的那个服务实例很快就消失了。不是变成了红色的不健康状态而是直接从列表里被删除了。这在以前用 Zookeeper 或者早期 Dubbo 的时候其实是不太一样的。那时候服务挂了通常只是显示不健康节点信息还会保留在那儿。为什么 Nacos 要默认把它直接删掉呢临时 vs 持久其实在 Nacos 的设计里实例是分两种的临时实例Ephemeral 和 持久实例Persistent。Spring Cloud Alibaba 默认给我们的配置就是临时实例。这两者最大的区别在于谁来维持心跳以及挂了之后怎么处理。临时实例默认客户端你的微服务主动给 Nacos 发心跳默认 5 秒一次。如果 Nacos 一段时间比如 30 秒没收到心跳它就默认你已经下线了直接把你从服务列表里剔除。持久实例客户端注册一次就不管了。Nacos 服务端会主动去探测这个 IP 通不通。我就在这儿你不注销我我就一直在。如果探测不通Nacos 只会把你标记为不健康但不会删除你。这条记录会一直留在列表里。为什么要默认选临时很多从传统架构转过来的同学可能会觉得保留历史记录不好吗持久化下来方便我排查问题啊。在物理机时代这确实没问题。因为那时候 IP 是固定的机器挂了修好重启IP 还是那个 IP。但现在Docker 和 K8s的普及环境变了。想象一下你的服务部署在 K8s 里每次发布更新旧的 Pod 被销毁新的 Pod 被创建。关键点是新 Pod 的 IP 地址通常是变的。如果你用的是持久实例每次重启Nacos 里就会多出几个不健康的旧 IP。发布几次之后你的服务列表里就会堆积成百上千个无效的 IP 地址。这不仅浪费存储还会导致客户端拉取服务列表时还得花精力去过滤那些已经不存在的节点。所以 Nacos 默认选择临时实例因为在云原生环境下IP 地址是随时可能回收的资源。服务挂了就是挂了直接清理掉给新 IP 腾位置保持服务列表的干净。深层原因CAP 的取舍除了 IP 变动还有一个更核心的原因涉及分布式系统的 CAP 理论。持久实例CP 模式因为它要求数据可靠Nacos 内部通常走Raft 协议。Raft 是强一致性的这意味着如果 Nacos 集群里的 Leader 挂了需要重新选举。在选举期间整个注册中心是不可写的。对于高频上下线的微服务来说因为网络抖动就导致服务注册不上这是很难接受的。临时实例AP 模式它走的是 Nacos 自研的 Distro 协议它的逻辑是高可用大于强一致。即使集群之间数据还没完全同步只要能让服务注册上来能让别人发现你不报错比什么都强。什么时候该用持久实例持久实例它主要适用的场景是那些IP 不怎么变、且极其重要的基础设施比如数据库 MySQL、Redis。有时候我们希望把 MySQL 也注册到 Nacos 里让微服务去发现数据库的地址。因为数据库通常是固定的即使它暂时挂了我们也不希望它从列表里消失。我们希望它只是显示异常等修好了IP 还是那个 IP业务能自动恢复。说在最后回到最初的问题为什么默认是临时实例因为在现在的微服务架构里活着比记住更重要。微服务应用是流动的资源用临时实例AP 模式。挂了就清理保持服务列表的有效性别让客户端调用到死节点。数据库/重资产是固定的资源用持久实例CP 模式。挂了保留记录方便运维排查。大家在 K8s 环境下用 Nacos建议就保持默认配置不要手动去开持久化模式否则你的控制台里可能会留下一堆清理不掉的无效数据。看完等于学会点个赞吧
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2414208.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!