调用触发事件通知
调用前后发生异常时的事件通知
功能描述
调用前、调用后和发生异常时,会触发三个事件 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 日:增强 en 文档 (#1798) (95a9f4f6c1c)