前两天遇到了一个问题,Nacos 中的永久服务删除不了,折腾了一番,最后还是顺利解决了。以下是原因分析和解决方案,建议先收藏,以备不时之需。

临时实例和持久化实例是 Nacos 1.0.0 中新增了一个特性。临时实例和持久化实例最大的区别是健康检查的方式:临时实例使用客户端主动上报的健康检查模式,而持久化实例使用服务端反向探测的模式。也就是说,如果是临时实例,那么客户端需要主动上报自己的健康状况,而持久化实例需要 Nacos 服务器端反向探测实例的健康状况。

而在这两种实例中,临时实例是可以自动删除非健康实例的,并且当所有的临时实例被删除之后,Nacos 中的服务也会被自动删除,这是临时服务的删除流程。但对于持久化实例来说,就没有那么简单了,因此持久化实例即使是非健康状态,也不会自动删除实例和服务,这个时候就需要我们手动删除服务了。

PS:持久化实例也有另一种叫法,叫做永久实例。



需要注意的是,在 Nacos 2.0 之前,一个服务中的实例既可以是临时实例也可以是持久化实例,但在 Nacos 2.0 时有了⼀些细微的调整。在 Nacos 2.0 之前,一个服务中的实例既可以是临时实例也可以是永久实例会给运维人员带来极大的困惑和运维复杂度。

与此同时,从系统架构来看,⼀个服务同时存在持久化及非持久化实例的场景也是存在⼀定矛盾的。这就导致该能力事实上并未被广泛使用。为了简化 Nacos 的服务数据模型,降低运维人员的复杂度,提升 Nacos 的易用性,在 Nacos 2.0 中将是否持久化的数据抽象至服务级别,且不再允许⼀个服务同时存在持久化实例和非持久化实例,也就是从 Nacos 2.0 之后,临时实例就变成了临时服务,持久化实例就变成了持久化服务,一个服务的整个生命周期只能有一种实例类型。

为什么需要两种服务类型?

以淘宝为例,双十一大促期间,流量会比平常高出很多,此时服务肯定需要增加更多实例来应对高并发,而这些实例在双十一之后就无需继续使用了,采用临时实例比较合适。而对于服务的一些常备实例,则使用永久实例更合适。

问题重现

但持久化服务在手动删除时候会报错,如下图所示:



当我们在 Nacos 控制台点击服务的“删除”按钮时,提示“caused: Service DEFAULT_GROUP@@XXX is not empty, can't be delete. Please unregister instance first;”,意思是不能删除,请先注销服务下的实例,于是我们进入服务实例列表,如下图所示:



服务实例里面没有注销按钮,只有“下线”按钮,难道在服务的“编辑”页面里面?于是我们又点击编辑按钮,看到如下信息:



服务编辑页面还是没有注销按钮,难道要把实例全部“下线”?于是我们尝试将所有的实例“下线”如下图所示:



然后再返回服务列表页面,点击“删除”按钮,发现还是原来的提示信息:



这可咋整嘞,一顿操作还是删除不了?

解决方案

我们知道除了控制台之外,还可以通过 Nacos SDK 或 OpenAPI 来操作 Nacos,而 OpenAPI 的操作成本是最低的,于是赶紧找出 Nacos 官方的 OpenAPI 文档,看一下如何通过 API 注销服务实例。

果然,功夫不负有心人,在官方文档中顺利的找到了注销的 API,如下图所示:



OpenAPI 地址:https://nacos.io/zh-cn/docs/open-api.html

PS:在这里感谢好友@二师兄,提供的思路。

OpenAPI 内容如下:



于是照着 API 文档构建了删除命令:

curl -X DELETE 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=spring-cloud-nacos-producer&groupName=DEFAULT_GROUP&namespaceId=public&ip=10.0.24.8&clusterName=DEFAULT&port=8081&ephemeral=false'

以上命令在 Nacos 服务器执行的结果如下图所示:



服务器返回了结果“OK”,打开 Nacos 服务实例列表看一下实例是否被正常注销:



果然有效果,持久化实例被顺利的注销了,于是使用同样的方法把实例 2 也注销一下,如下图所示:



当我把服务下的所有实例都注销之后,再去 Nacos 控制台发现服务也随之消失了,如下图所示:



细心一点的朋友会发现,之前的服务并不会立马消失了,而是变成空服务了,要手动切换一下“隐藏空服务”才能展示出来,但有它和没它的效果是一样的了,我们可以创建和它名字相同的临时实例了,这就和删除的效果一样了,如果没有被删除是创建不了临时实例的,所以从逻辑上理解,我们可以认为它已经被删除了。

总结

Nacos 中有两种实例:临时实例和持久化实例(永久实例),在 Nacos 2.0 之后,每个服务中只能保存一种类型的实例,也就是实例类型已经升级成了服务类型了。对于临时服务来说,无需删除,当临时服务中的所有实例都被删除之后,临时服务也会被自动删除;而永久服务需要先通过 OpenAPI 注销所有的实例,当所有实例被注销之后,服务也被删除了。

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java中文社群

Java面试合集:https://gitee.com/mydb/interview

Nacos中服务删除不了,怎么办?的更多相关文章

  1. 当在本地磁盘服务(Windows)中无法删除指定分区时的解决方案

    有时候,我们在使用Windows管理磁盘分区时,可能会出现部分分区无法删除的情况,也就是说右键快捷菜单中没有删除卷的操作项. 此时,我们可以按照如下的步骤进行操作即可完成: Step 1: 以管理员身 ...

  2. SpringCloud+Nacos实现服务配置中心(Hoxton版本)

    关于 Nacos Spring Cloud 的详细文档请参看:Nacos Config和Nacos Discovery. 通过 Nacos Server 和 spring-cloud-starter- ...

  3. 如何手动添加Windows服务和如何把一个服务删除

    windows 手动添加服务方法一:修改注册表 在注册表编辑器,展开分支"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services" ...

  4. Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

    自Spring Cloud Alibaba发布第一个Release以来,就备受国内开发者的高度关注.虽然Spring Cloud Alibaba还没能纳入Spring Cloud的主版本管理中,但是凭 ...

  5. SpringCloud微服务:阿里开源组件Nacos,服务和配置管理

    源码地址:GitHub·点这里||GitEE·点这里 一.阿里微服务简介 1.基础描述 Alibaba-Cloud致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开 ...

  6. SpringCloud第二代实战系列:一文搞定Nacos实现服务注册与发现

    一.背景:SpringCloud 生态圈 在正式开始本篇文章之前我们先岔开来讲一下SpringCloud的生态圈. SpringCloud大家都比较熟悉了,它制定了分布式系统的标准规范,做了高度抽象和 ...

  7. Spring Cloud Alibaba系列(二)nacos作为服务配置中心

    Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...

  8. (十七)整合 Zookeeper组件,管理架构中服务协调

    整合 Zookeeper组件,管理架构中服务协调 1.Zookeeper基础简介 1.1 基本理论 1.2 应用场景 2.安全管理操作 2.1 操作权限 2.2 认证方式: 2.3 Digest授权流 ...

  9. SpringCloud学习之【NACOS实现服务的注册与发现】

    根据nacos官方的介绍,Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理. 具有服务发现和服务健康监 ...

随机推荐

  1. spring boot + redis --- 心得

    1.前言 习惯使用springMVC 配置 redis ,现在使用spring boot ,得好好总结怎么在spring boot 配置和使用 ,区别真的挺大的. 2.环境 spring boot  ...

  2. 移动端字体图标不显示的Bug

    用16进制编码的字体图标在部分小米机型显示不正常. 测试机型:小米1,小米1s,小米2浏览器:微信6.1内置浏览器,QQ浏览器 5.7 X5内核字体图标:不显示svg图标:显示正常 以下来自额微信内置 ...

  3. Ubuntu16安装Nvidia驱动(GTX1060显卡)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. MySQL使用时间作为判断条件

    背景:在开发过程中,我们经常需要根据时间作为判断条件来查询数据,例如:当月,当日,当前小时,几天内...... 1. 当月 我们只需要使用一个mysql的MONTH(date)函数即可实现.(注意判断 ...

  5. TextBox,RichTextBox设置行高

    /// <summary> /// 设置行距 /// </summary> /// <param name="ctl">控件</param ...

  6. C#图片转成流

    Bitmap b = new Bitmap(Server.MapPath(ppath)); Stream ms = new MemoryStream(); b.Save(ms, System.Draw ...

  7. Cesium入门3 - Cesium目录框架结构

    Cesium入门3 - Cesium目录框架结构 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ app目录 下 ...

  8. Django db使用MySQL连接池

    Django db使用MySQL连接池 Sep 25 2016 Django db模块本身不支持MySQL连接池,只有一个配置CONN_MAX_AGE连接最大存活时间,如果WSGI服务器使用了线程池技 ...

  9. gin的源码解读4-gin的路由算法

    gin的路由算法 gin的是路由算法其实就是一个Trie树(也就是前缀树). 有关数据结构的可以自己去网上找相关资料查看. 注册路由预处理 我们在使用gin时通过下面的代码注册路由 普通注册 rout ...

  10. find -or 用法

    find /opt/IBM/WebSphere85/ -name *loggeter* - or -name *loggetter* | xargs rm -rf