Spring Cloud Alibaba Nacos路由策略之保護閾值!

在 Nacos 的路由策略中有 3 個比較重要的內容:權重、保護閾值和就近訪問。因為這 3 個內容都是彼此獨立的,所以今天我們就單獨拎出「保護閾值」來詳細聊聊。

保護閾值

保護閾值(ProtectThreshold):為了防止因過多實例故障,導致所有流量全部流入剩餘健康實例,繼而造成流量壓力將剩餘健康實例被壓垮形成雪崩效應。應將健康保護閾值定義為⼀個 0 到 1 之間的浮點數。當域名健康實例數佔總服務實例數的比例小於該值時,無論實例是否健康,都會將這個(健康或不健康的)實例返回給客戶端。這樣做雖然損失了⼀部分流量,但是保證了集群中剩餘健康實例能正常工作。

也就是說,保護閾值是設置集群中健康實例佔比允許的最小值,它需要設置一個 0-1 的浮點值,默認值為 0,當集群中的健康實例佔比小於設置的保護閾值時,就會觸發閾值保護功能。保護閾值可在服務詳情中查詢和設置,如下圖所示:
image.png

如何理解保護閾值?

要理解保護閾值先要明確一個前提條件:對於 Nacos 的註冊中心功能來說,Nacos 有一個天然的職責,是將服務消費者(Consumer)的請求轉發給某個健康的服務提供者(Provider)。
但在執行的流程中,可能會出現一種極端的情況,比如某個服務有 100 個實例,其中 99 個實例都宕機了,只剩下一個健康的實例,這個時候如果把所有的請求都轉發到這一個健康實例上就會造成雪崩效應,最終導致業務系統崩潰。
為了防止這種極端情況,於是就有了「保護閾值」,保護閾值一旦被觸發,那麼 Nacos 將會把請求轉發給所有服務實例,也就是健康實例+非健康實例,這樣可能會損失了⼀部分流量,但能保證集群中剩餘的健康實例能正常工作。

保護閾值觸發條件:(實際健康實例/總服務實例)≤設置的保護閾值

設置保護閾值

我們可以通過「編輯服務」來設置保護閾值,如下圖所示:
image.png

觸發保護閾值

接下來我們創建一個服務測試一下保護閾值的功能,在創建的服務中添加兩個實例,如下圖所示:
image.png
image.png
默認情況下服務實例都是健康的,接下來我們將保護閾值設置為 0.8,也就是健康實例的最低要求是 80%,如果健康實例佔比小於此值就會觸發保護閾值,如下圖所示:
image.png
當所有節點都健康時,觀察服務列表頁面,可以看出並未觸發保護閾值的功能,如下圖所示:
image.png
此時我們手動停止一個服務實例,如下圖所示:
image.png
這是健康實例的佔比就從 100%,下降到了 50%,小於了設置的保護閾值 0.8(80%),接下來返回服務列表頁面,可以看到保護閾值功能被觸發了:
image.png
此時,我們再去訪問服務就會看到,部分請求會轉發到非健康實例,也就是訪問會出錯,如下圖所示:
觸發保護閾值.gif

未觸發保護閾值

接下來我們降低保護閾值,將保護閾值設置為 0.3,也就是健康實例佔比最低要求是 30%,否則會觸發閾值保護,如下圖所示:
image.png
而此時因為我們健康實例佔比是 50%,大於設置的閾值保護 0.3,所以就不會觸發閾值保護,這點可以在服務列表中觀察到:
image.png
當未觸發保護閾值時,Nacos 會把所有請求都轉發到健康的實例上,所以每次都能正常的訪問服務,執行效果如下圖所示:
保護閾值未生效.gif

總結

保護閾值是為了防止因過多實例故障,導致所有流量全部流入剩餘健康實例,繼而造成流量壓力將剩餘健康實例被壓垮形成雪崩效應。它的默認值是 0,取值範圍應該是 0-1 的浮點數。此值是定義集群中允許健康實例佔比的最小值,如果實際健康服務佔比小於或等於此值,就會觸發保護閾值,那麼 Nacos 就會將全部實例:健康實例 + 非健康實例全部返回給調用者,而當保護閾值未觸發時,Nacos 只會把健康實例返回給調用者。

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

公眾號:Java中文社群

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