Nacos中服務刪除不了,怎么辦?


前兩天遇到了一個問題,Nacos 中的永久服務刪除不了,折騰了一番,最后還是順利解決了。以下是原因分析和解決方案,建議先收藏,以備不時之需。

臨時實例和持久化實例是 Nacos 1.0.0 中新增了一個特性。臨時實例和持久化實例最大的區別是健康檢查的方式:臨時實例使用客戶端主動上報的健康檢查模式,而持久化實例使用服務端反向探測的模式。也就是說,如果是臨時實例,那么客戶端需要主動上報自己的健康狀況,而持久化實例需要 Nacos 服務器端反向探測實例的健康狀況。

而在這兩種實例中,臨時實例是可以自動刪除非健康實例的,並且當所有的臨時實例被刪除之后,Nacos 中的服務也會被自動刪除,這是臨時服務的刪除流程。但對於持久化實例來說,就沒有那么簡單了,因此持久化實例即使是非健康狀態,也不會自動刪除實例和服務,這個時候就需要我們手動刪除服務了。

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

image.png
需要注意的是,在 Nacos 2.0 之前,一個服務中的實例既可以是臨時實例也可以是持久化實例,但在 Nacos 2.0 時有了⼀些細微的調整。在 Nacos 2.0 之前,一個服務中的實例既可以是臨時實例也可以是永久實例會給運維人員帶來極大的困惑和運維復雜度。

與此同時,從系統架構來看,⼀個服務同時存在持久化及非持久化實例的場景也是存在⼀定矛盾的。這就導致該能力事實上並未被廣泛使用。為了簡化 Nacos 的服務數據模型,降低運維人員的復雜度,提升 Nacos 的易用性,在 Nacos 2.0 中將是否持久化的數據抽象至服務級別,且不再允許⼀個服務同時存在持久化實例和非持久化實例,也就是從 Nacos 2.0 之后,臨時實例就變成了臨時服務,持久化實例就變成了持久化服務,一個服務的整個生命周期只能有一種實例類型。

為什么需要兩種服務類型?

以淘寶為例,雙十一大促期間,流量會比平常高出很多,此時服務肯定需要增加更多實例來應對高並發,而這些實例在雙十一之后就無需繼續使用了,采用臨時實例比較合適。而對於服務的一些常備實例,則使用永久實例更合適。

問題重現

但持久化服務在手動刪除時候會報錯,如下圖所示:
永久服務不能刪除.gif
當我們在 Nacos 控制台點擊服務的“刪除”按鈕時,提示“caused: Service DEFAULT_GROUP@@XXX is not empty, can't be delete. Please unregister instance first;”,意思是不能刪除,請先注銷服務下的實例,於是我們進入服務實例列表,如下圖所示:
image.png
服務實例里面沒有注銷按鈕,只有“下線”按鈕,難道在服務的“編輯”頁面里面?於是我們又點擊編輯按鈕,看到如下信息:
image.png
服務編輯頁面還是沒有注銷按鈕,難道要把實例全部“下線”?於是我們嘗試將所有的實例“下線”如下圖所示:
image.png
然后再返回服務列表頁面,點擊“刪除”按鈕,發現還是原來的提示信息:
image.png
這可咋整嘞,一頓操作還是刪除不了?

解決方案

我們知道除了控制台之外,還可以通過 Nacos SDK 或 OpenAPI 來操作 Nacos,而 OpenAPI 的操作成本是最低的,於是趕緊找出 Nacos 官方的 OpenAPI 文檔,看一下如何通過 API 注銷服務實例。
果然,功夫不負有心人,在官方文檔中順利的找到了注銷的 API,如下圖所示:
image.png
OpenAPI 地址:https://nacos.io/zh-cn/docs/open-api.html

PS:在這里感謝好友@二師兄,提供的思路。

OpenAPI 內容如下:
image.png
於是照着 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 服務器執行的結果如下圖所示:
image.png
服務器返回了結果“OK”,打開 Nacos 服務實例列表看一下實例是否被正常注銷:
image.png
果然有效果,持久化實例被順利的注銷了,於是使用同樣的方法把實例 2 也注銷一下,如下圖所示:
image.png
當我把服務下的所有實例都注銷之后,再去 Nacos 控制台發現服務也隨之消失了,如下圖所示:
image.png
細心一點的朋友會發現,之前的服務並不會立馬消失了,而是變成空服務了,要手動切換一下“隱藏空服務”才能展示出來,但有它和沒它的效果是一樣的了,我們可以創建和它名字相同的臨時實例了,這就和刪除的效果一樣了,如果沒有被刪除是創建不了臨時實例的,所以從邏輯上理解,我們可以認為它已經被刪除了。

總結

Nacos 中有兩種實例:臨時實例和持久化實例(永久實例),在 Nacos 2.0 之后,每個服務中只能保存一種類型的實例,也就是實例類型已經升級成了服務類型了。對於臨時服務來說,無需刪除,當臨時服務中的所有實例都被刪除之后,臨時服務也會被自動刪除;而永久服務需要先通過 OpenAPI 注銷所有的實例,當所有實例被注銷之后,服務也被刪除了。

是非審之於己,毀譽聽之於人,得失安之於數。

公眾號:Java中文社群

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM