Dubbo3 應(yīng)用級服務(wù)發(fā)現(xiàn)地址遷移規(guī)則說明

2022-04-12 13:44 更新

本文具體說明了地址遷移過程中使用的規(guī)則體信息,用戶可以根據(jù)自己需求定制適合自己的遷移規(guī)則。

狀態(tài)模型

在 Dubbo 3 之前地址注冊模型是以接口級粒度注冊到注冊中心的,而 Dubbo 3 全新的應(yīng)用級注冊模型注冊到注冊中心的粒度是應(yīng)用級的。從注冊中心的實現(xiàn)上來說是幾乎不一樣的,這導(dǎo)致了對于從接口級注冊模型獲取到的 invokers 是無法與從應(yīng)用級注冊模型獲取到的 invokers 進行合并的。為了幫助用戶從接口級往應(yīng)用級遷移,Dubbo 3 設(shè)計了 Migration 機制,基于三個狀態(tài)的切換實現(xiàn)實際調(diào)用中地址模型的切換。

http://imgs/v3/migration/migration-1.png

當(dāng)前共存在三種狀態(tài),F(xiàn)ORCE_INTERFACE(強制接口級),APPLICATION_FIRST(應(yīng)用級優(yōu)先)、FORCE_APPLICATION(強制應(yīng)用級)。

FORCE_INTERFACE:只啟用兼容模式下接口級服務(wù)發(fā)現(xiàn)的注冊中心邏輯,調(diào)用流量 100% 走原有流程 APPLICATION_FIRST:開啟接口級、應(yīng)用級雙訂閱,運行時根據(jù)閾值和灰度流量比例動態(tài)決定調(diào)用流量走向 FORCE_APPLICATION:只啟用新模式下應(yīng)用級服務(wù)發(fā)現(xiàn)的注冊中心邏輯,調(diào)用流量 100% 走應(yīng)用級訂閱的地址

規(guī)則體說明

規(guī)則采用 yaml 格式配置,具體配置下參考如下:

key: 消費者應(yīng)用名(必填)
step: 狀態(tài)名(必填)
threshold: 決策閾值(默認(rèn)1.0)
proportion: 灰度比例(默認(rèn)100)
delay: 延遲決策時間(默認(rèn)0)
force: 強制切換(默認(rèn) false)
interfaces: 接口粒度配置(可選)
  - serviceKey: 接口名(接口 + : + 版本號)(必填)
    threshold: 決策閾值
    proportion: 灰度比例
    delay: 延遲決策時間
    force: 強制切換
    step: 狀態(tài)名(必填)
  - serviceKey: 接口名(接口 + : + 版本號)
    step: 狀態(tài)名
applications: 應(yīng)用粒度配置(可選)
  - serviceKey: 應(yīng)用名(消費的上游應(yīng)用名)(必填)
    threshold: 決策閾值
    proportion: 灰度比例
    delay: 延遲決策時間
    force: 強制切換
    step: 狀態(tài)名(必填)
  • key: 消費者應(yīng)用名
  • step: 狀態(tài)名(FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION)
  • threshold: 決策閾值(浮點數(shù),具體含義參考后文)
  • proportion: 灰度比例(0~100,決定調(diào)用次數(shù)比例)
  • delay: 延遲決策時間(延遲決策的時間,實際等待時間為 1~2 倍 delay 時間,取決于注冊中心第一次通知的時間,對于目前 Dubbo 的注冊中心實現(xiàn)次配置項保留 0 即可)
  • force: 強制切換(對于 FORCE_INTERFACE、FORCE_APPLICATION 是否不考慮決策直接切換,可能導(dǎo)致無地址調(diào)用失敗問題)
  • interfaces: 接口粒度配置

參考配置示例如下:

key: demo-consumer
step: APPLICATION_FIRST
threshold: 1.0
proportion: 60
delay: 0
force: false
interfaces:
  - serviceKey: DemoService:1.0.0
    threshold: 0.5
    proportion: 30
    delay: 0
    force: true
    step: APPLICATION_FIRST
  - serviceKey: GreetingService:1.0.0
    step: FORCE_APPLICATION

配置方式說明

1. 配置中心配置文件下發(fā)(推薦)

  • Key: 消費者應(yīng)用名 + “.migration”
  • Group: DUBBO_SERVICEDISCOVERY_MIGRATION

? 配置項內(nèi)容參考上一節(jié)

程序啟動時會拉取此配置作為最高優(yōu)先級啟動項,當(dāng)配置項為啟動項時不執(zhí)行檢查操作,直接按狀態(tài)信息達到終態(tài)。 程序運行過程中收到新配置項將執(zhí)行遷移操作,過程中根據(jù)配置信息進行檢查,如果檢查失敗將回滾為遷移前狀態(tài)。遷移是按接口粒度執(zhí)行的,也即是如果一個應(yīng)用有 10 個接口,其中 8 個遷移成功,2 個失敗,那終態(tài) 8 個遷移成功的接口將執(zhí)行新的行為,2 個失敗的仍為舊狀態(tài)。如果需要重新觸發(fā)遷移可以通過重新下發(fā)規(guī)則達到。

注:如果程序在遷移時由于檢查失敗回滾了,由于程序無回寫配置項行為,所以如果此時程序重啟了,那么程序會直接按照新的行為不檢查直接初始化。

2. 啟動參數(shù)配置

  • 配置項名:dubbo.application.service-discovery.migration
  • 允許值范圍:FORCE_INTERFACE、APPLICATION_FIRST、FORCE_APPLICATION

此配置項可以通過環(huán)境變量或者配置中心傳入,啟動時優(yōu)先級比配置文件低,也即是當(dāng)配置中心的配置文件不存在時讀取此配置項作為啟動狀態(tài)。

3. 本地文件配置

配置項名 默認(rèn)值 說明
dubbo.migration.file dubbo-migration.yaml 本地配置文件路徑
dubbo.application.migration.delay 60000 配置文件延遲生效時間(毫秒)

配置文件中格式與前文提到的規(guī)則一致

本地文件配置方式本質(zhì)上是一個延時配置通知的方式,本地文件不會影響默認(rèn)啟動方式,當(dāng)達到延時時間后觸發(fā)推送一條內(nèi)容和本地文件一致的通知。這里的延時時間與規(guī)則體中的 delay 字段無關(guān)聯(lián)。 本地文件配置方式可以保證啟動以默認(rèn)行為初始化,當(dāng)達到延時時觸發(fā)遷移操作,執(zhí)行對應(yīng)的檢查,避免啟動時就以終態(tài)方式啟動。

決策說明

1. 閾值探測

閾值機制旨在進行流量切換前的地址數(shù)檢查,如果應(yīng)用級的可使用地址數(shù)與接口級的可用地址數(shù)對比后沒達到閾值將檢查失敗。

核心代碼如下:

if (((float) newAddressSize / (float) oldAddressSize) >= threshold) {
    return true;
}
return false;

同時 MigrationAddressComparator 也是一個 SPI 拓展點,用戶可以自行拓展,所有檢查的結(jié)果取交集。

2. 灰度比例

灰度比例功能僅在應(yīng)用級優(yōu)先狀態(tài)下生效。此功能可以讓用戶自行決定調(diào)用往新模式應(yīng)用級注冊中心地址的調(diào)用數(shù)比例。灰度生效的前提是滿足了閾值探測,在應(yīng)用級優(yōu)先狀態(tài)下,如果閾值探測通過,currentAvailableInvoker 將被切換為對應(yīng)應(yīng)用級地址的 invoker;如果探測失敗 currentAvailableInvoker 仍為原有接口級地址的 invoker。

流程圖如下: 探測階段  http://imgs/v3/migration/migration-2.png 調(diào)用階段  http://imgs/v3/migration/migration-3.png

核心代碼如下:

// currentAvailableInvoker is based on MigrationAddressComparator's result
if (currentAvailableInvoker != null) {
    if (step == APPLICATION_FIRST) {
        // call ratio calculation based on random value
        if (ThreadLocalRandom.current().nextDouble(100) > promotion) {
            return invoker.invoke(invocation);
        }
    }
    return currentAvailableInvoker.invoke(invocation);
}

切換過程說明

地址遷移過程中涉及到了三種狀態(tài)的切換,為了保證平滑遷移,共有 6 條切換路徑需要支持,可以總結(jié)為從強制接口級、強制應(yīng)用級往應(yīng)用級優(yōu)先切換;應(yīng)用級優(yōu)先往強制接口級、強制應(yīng)用級切換;還有強制接口級和強制應(yīng)用級互相切換。 對于同一接口切換的過程總是同步的,如果前一個規(guī)則還未處理完就收到新規(guī)則則回進行等待。

1. 切換到應(yīng)用級優(yōu)先

從強制接口級、強制應(yīng)用級往應(yīng)用級優(yōu)先切換本質(zhì)上是從某一單訂閱往雙訂閱切換,保留原有的訂閱并創(chuàng)建另外一種訂閱的過程。這個切換模式下規(guī)則體中配置的 delay 配置不會生效,也即是創(chuàng)建完訂閱后馬上進行閾值探測并決策選擇某一組訂閱進行實際優(yōu)先調(diào)用。由于應(yīng)用級優(yōu)先模式是支持運行時動態(tài)進行閾值探測,所以對于部分注冊中心無法啟動時即獲取全量地址的場景在全部地址通知完也會重新計算閾值并切換。 應(yīng)用級優(yōu)先模式下的動態(tài)切換是基于服務(wù)目錄(Directory)的地址監(jiān)聽器實現(xiàn)的。  http://imgs/v3/migration/migration-4.png

2. 應(yīng)用級優(yōu)先切換到強制

應(yīng)用級優(yōu)先往強制接口級、強制應(yīng)用級切換的過程是對雙訂閱的地址進行檢查,如果滿足則對另外一份訂閱進行銷毀,如果不滿足則回滾保留原來的應(yīng)用級優(yōu)先狀態(tài)。 如果用戶希望這個切換過程不經(jīng)過檢查直接切換可以通過配置 force 參數(shù)實現(xiàn)。  http://imgs/v3/migration/migration-5.png

3. 強制接口級和強制應(yīng)用級互相切換

強制接口級和強制應(yīng)用級互相切換需要臨時創(chuàng)建一份新的訂閱,判斷新的訂閱(即閾值計算時使用新訂閱的地址數(shù)去除舊訂閱的地址數(shù))是否達標(biāo),如果達標(biāo)則進行切換,如果不達標(biāo)會銷毀這份新的訂閱并且回滾到之前的狀態(tài)。  http://imgs/v3/migration/migration-6.png



以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號