呼叫觸發事件通知

呼叫前後發生異常時的事件通知

功能描述

在呼叫之前、呼叫之後和發生異常時,會觸發三個事件:`oninvoke`、`onreturn` 和 `onthrow`。您可以配置在事件發生時通知哪個類別的哪個方法。

參考用例

https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-notify

使用場景

在呼叫服務方法之前,我們可以記錄開始時間,在呼叫結束後,我們可以計算整個呼叫成本。當發生異常時,我們可以在呼叫服務前後發出警告或列印錯誤日誌,或者記錄請求日誌和回應日誌。

使用方法

服務提供者和消費者共用服務介面

interface IDemoService {
    public Person get(int id);
}

服務提供者實作

class NormalDemoService implements IDemoService {
    public Person get(int id) {
        return new Person(id, "charles`son", 4);
    }
}

服務提供者配置

<dubbo:application name="rpc-callback-demo" />
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<bean id="demoService" class="org.apache.dubbo.callback.implicit.NormalDemoService" />
<dubbo:service interface="org.apache.dubbo.callback.implicit.IDemoService" ref="demoService" version="1.0.0" group="cn"/>

服務消費者回呼介面

interface Notify {
    public void onreturn(Person msg, Integer id);
    public void onthrow(Throwable ex, Integer id);
}

服務消費者回呼實作

class NotifyImpl implements Notify {
    public Map<Integer, Person> ret = new HashMap<Integer, Person>();
    public Map<Integer, Throwable> errors = new HashMap<Integer, Throwable>();
    
    public void onreturn(Person msg, Integer id) {
        System.out.println("onreturn:" + msg);
        ret. put(id, msg);
    }
    
    public void onthrow(Throwable ex, Integer id) {
        errors. put(id, ex);
    }
}

服務消費者回呼配置

兩者有以下組合

  • 非同步回呼模式:`async=true onreturn="xxx"`
  • 同步回呼模式:`async=false onreturn="xxx"`
  • 非同步無回呼:`async=true`
  • 同步無回呼:`async=false`

`callback` 和 `async` 函式是正交分解的,`async=true` 表示是否立即返回結果,`async=false` 是預設值,`onreturn` 表示是否需要回呼。

<bean id="demoCallback" class = "org.apache.dubbo.callback.implicit.NotifyImpl" />
<dubbo:reference id="demoService" interface="org.apache.dubbo.callback.implicit.IDemoService" version="1.0.0" group="cn">
      <dubbo:method name="get" async="true" onreturn = "demoCallback.onreturn" onthrow="demoCallback.onthrow" />
</dubbo:reference>

測試程式碼

IDemoService demoService = (IDemoService) context. getBean("demoService");
NotifyImpl notify = (NotifyImpl) context. getBean("demoCallback");
int requestId = 2;
Person ret = demoService. get(requestId);
Assert.assertEquals(null, ret);
//for Test: It is only used to illustrate that the callback is called normally, and the specific implementation of the business is determined by itself.
for (int i = 0; i < 10; i++) {
    if (!notify.ret.containsKey(requestId)) {
        Thread. sleep(200);
    } else {
        break;
    }
}
Assert.assertEquals(requestId, notify.ret.get(requestId).getId());

上次修改時間:2023 年 1 月 2 日:增強英文文件 (#1798) (95a9f4f6c1c)