当前位置: 代码迷 >> 综合 >> dubbo读书笔记八 事件通知
  详细解决方案

dubbo读书笔记八 事件通知

热度:65   发布时间:2023-10-13 18:53:28.0

事件通知

在调用之前、调用之后、出现异常时,会触发 oninvokeonreturnonthrow 三个事件,可以配置当事件发生时,通知哪个类的哪个方法 [1]。

服务提供者与消费者共享服务接口

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"/>

服务消费者 Callback 接口

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

服务消费者 Callback 实现

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);}
}

服务消费者 Callback 配置

<bean id ="demoCallback" class = "org.apache.dubbo.callback.implicit.NofifyImpl" />
<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>

callback 与 async 功能正交分解,async=true 表示结果是否马上返回,onreturn 表示是否需要回调。

两者叠加存在以下几种组合情况 [2]:

  • 异步回调模式:async=true onreturn="xxx"
  • 同步回调模式:async=false onreturn="xxx"
  • 异步无回调 :async=true
  • 同步无回调 :async=false

测试代码

IDemoService demoService = (IDemoService) context.getBean("demoService");
NofifyImpl notify = (NofifyImpl) context.getBean("demoCallback");
int requestId = 2;
Person ret = demoService.get(requestId);
Assert.assertEquals(null, ret);
//for Test:只是用来说明callback正常被调用,业务具体实现自行决定.
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());

  1. 支持版本:2.0.7 之后 ??

  2. async=false 默认 ??

  相关解决方案