本地偽裝

瞭解如何在 Dubbo3 中使用本地偽裝實現服務降級

功能描述

Dubbo3 中有一種機制可以實現輕量級服務降級,即本地偽裝1

使用場景

本地偽裝通常用於服務降級。例如,對於驗證服務,當所有服務提供者都掛斷時,如果服務消費者此時發起遠端呼叫,則呼叫將失敗並拋出 RpcException

為了避免這種直接拋出異常的情況,客戶端可以使用本地偽裝來提供 Mock 資料並返回授權失敗。

使用方法

啟用 Mock 配置

在 Spring XML 配置檔案中以下列方式配置

<dubbo:reference interface="com.foo.BarService" mock="true" />

<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />

在專案中提供 Mock 實現2

package com.foo;
public class BarServiceMock implements BarService {
    public String sayHello(String name) {
        // You can fake fault-tolerant data, this method is only executed when RpcException occurs
        return "fault tolerance data";
    }
}

使用 return 關鍵字模擬返回值

使用 return 返回一個由字串表示的物件作為 Mock 的返回值。合法的字串可以是

  • :代表空,返回基本類型的預設值、集合類的空值以及自訂實體類的空物件3
  • null:返回 null
  • true:返回 true
  • false:返回 false
  • JSON 字串:返回 JSON 字串反序列化後獲得的物件

例如,如果服務的消費者經常需要使用 try-catch 來捕捉異常,例如

public class DemoService {

    public Offer findOffer(String offerId) {
        Offer offer = null;
        try {
            offer = offerService. findOffer(offerId);
        } catch (RpcException e) {
            logger. error(e);
        }

        return offer;
    }
}

那麼可以考慮改為 Mock 實現,並在 Mock 實現中 return null。如果只是想簡單地忽略異常,則在 2.0.11 及以上版本中可以使用

<dubbo:reference interface="com.foo.BarService" mock="return null" />

使用 throw 關鍵字 Mock 拋出異常

使用 throw 返回一個 Exception 物件作為 Mock 的返回值。

當呼叫失敗時,會拋出預設的 RPCException。


<dubbo:reference interface="com.foo.BarService" mock="throw"/>

當呼叫中發生錯誤時,拋出指定的 Exception4


<dubbo:reference interface="com.foo.BarService" mock="throw com.foo.MockException"/>

使用 force 和 fail 關鍵字來配置 Mock 的行為。

force: 表示強制使用 Mock 行為,在這種情況下不會進行遠端呼叫。

fail: 與預設行為一致,僅在遠端呼叫發生錯誤時才使用 mock 行為。也就是說,配置時實際上可以不使用 fail 關鍵字,而直接使用 throwreturn

force:fail: 都支援與 throwreturn 組合使用。

強制返回指定的值。


<dubbo:reference interface="com.foo.BarService" mock="force:return fake"/>

強制拋出指定的異常。


<dubbo:reference interface="com.foo.BarService" mock="force:throw com.foo.MockException"/>

當呼叫失敗時,返回指定的值。


<dubbo:reference interface="com.foo.BarService" mock="fail:return fake"/>

<!-- Equivalent to the following writing -->
<dubbo:reference interface="com.foo.BarService" mock="return fake"/>

當呼叫失敗時,拋出異常。


<dubbo:reference interface="com.foo.BarService" mock="fail:throw com.foo.MockException"/>

<!-- Equivalent to the following writing -->
<dubbo:reference interface="com.foo.BarService" mock="throw com.foo.MockException"/>

在方法層級配置 Mock。

Mock 可以在方法層級指定,假設 com.foo.BarService 上有多個方法,我們可以單獨為 sayHello() 方法指定 Mock 行為。

具體配置如下。在此範例中,每當呼叫 sayHello() 時,都會強制返回「fake」。


<dubbo:reference id="demoService" check="false" interface="com.foo.BarService">
    <dubbo:parameter key="sayHello.mock" value="force:return fake"/>
</dubbo:reference>

注意事項


  1. Mock 是 Stub 的一個子集,方便服務提供者在客戶端實現容錯邏輯。因為通常需要在發生 RpcException(例如網路故障、逾時等)時執行容錯,而在發生業務異常(例如登入錯誤的使用者名稱和密碼)時不需要容錯。如果使用 Stub,您可能需要捕捉並依賴 RpcException 類別,但使用 Mock 可以不依賴 RpcException,因為它的約定是僅在發生 RpcException 時才執行。 ↩︎

  2. 在介面旁邊放置一個 Mock 實作,該實作實現 BarService 介面並具有無參數建構子。同時,如果設定檔中未明確指定 Mock 類別,則需要確保 Mock 類別的完整類別名稱的格式為「原始完整類別名稱 + Mock」,例如 com.foo.BarServiceMock,否則 Mock 將會失敗。 ↩︎

  3. 如果返回值是一個實體類別,則它將返回一個具有預設值的空物件,而不是 null。 ↩︎

  4. 自訂異常必須具有一個以 String 作為輸入參數的建構子,該建構子將用於接收異常資訊。 ↩︎


最後修改日期:2023 年 1 月 2 日: 增強英文文件 (#1798) (95a9f4f6c1c)