13.dubbo异步调用、本地调用、参数回调、事件通知

来源:互联网 发布:天庭淘宝店 宁小北 编辑:程序博客网 时间:2024/06/05 02:13

1.异步调用

dubbo使用netty实现nio。RPC的异步调用也可以基于nio来实现。通常异步调用时开启多线程来同时执行任务而任务之间不会相互等待对方的结果,直接使用nio来实现异步调用可以不用新开多线程相对来说开销较小。异步调用每次结果的返回使用future来获取调用结果。

官方给的图如下:


在调用方的线程中使用RpcContext来获取本次调用的futrue拿到调用的结果。途中虚线的部分2、6是基于nio框架来实现的。每次调用时由netty创建一个nio线程,这个线程用于双方的建立连接,异步调用也基于它实现。

(1)消费者

在引用提供者接口的时候开起异步调用

    <!-- 引用提供者接口,开启异步功能 -->    <dubbo:reference id="modelService" interface="com.tyf.d_zk_provider.modelService" >        <dubbo:method name="serviceTest" async="true" />    </dubbo:reference> 

异步调用时会立即返回一个null结果,最终结果通过RpcCnotext的future拿到

       // 获取远程服务代理           modelService service = (modelService)context.getBean("modelService");           // 远程调用会立即返回null           System.out.println("立即返回结果: "+service.serviceTest("data"));           // 获取当前调用线程的future,用于监听异步调用的结果           Future<String> future = RpcContext.getContext().getFuture();           System.out.println("异步返回的结果: "+future.get());


有时候只是关心异步调用但是不关心返回结果的时候可以设置return为false这样立即返回null但是RpcContext中不会创建future以此增加性能

    <!-- 引用提供者接口,开启异步功能,设置不返回解雇 -->    <dubbo:reference id="modelService" interface="com.tyf.d_zk_provider.modelService" >        <dubbo:method name="serviceTest" async="true" return="false" />    </dubbo:reference> 

2.本地调用

3.参数回调

提供者暴露的接口实现中可能持有一个监听器接口的引用,某个方法被远程调用时需要触发这些监听器。消费者在远程调用暴露的接口实现时可以远程地给他设置监听器,具体的监听器实现由消费者来掌控。这样可以让提供者调用消费者设定好的监听器代码。
下面例子消费者远程给服务添加监听器、远程实现监听器的逻辑、然后远程触发监听器
(1)服务提供者
监听器接口
package com.tyf.d_zk_provider;public interface Callback {public void msg_changed(String msg);}
暴露的接口实现
package com.tyf.d_zk_provider;import java.util.ArrayList;import java.util.List;public class modelServiceImpl implements modelService {//监听器集合public final List<Callback> lists = new ArrayList<Callback>();//添加监听器public void addCallback(Callback callback) {lists.add(callback);}//发送一个事件,触发监听器public void send_msg(String msg){//传入新msg就触发集合中所有监听器,监听器只是一个接口具体要实现什么由调用方设计for(Callback cback : lists){cback.msg_changed(msg);}}}
将添加监听器、触发监听器的方法暴露出去。具体的监听器实现由消费者设置
提供者配置文件中指明哪个方法会添加监听器、添加哪一种监听器
    <dubbo:service interface="com.tyf.d_zk_provider.modelService"   ref="modelService" connections="1" callbacks="1000">        <dubbo:method name="addCallback">           <dubbo:argument type="com.tyf.d_zk_provider.Callback" callback="true" />    </dubbo:method>    </dubbo:service>  

(2)消费者
和提供者 一模一样的监听器接口
package com.tyf.d_zk_provider;public interface Callback {public void msg_changed(String msg);}
引用服务,并实现具体监听器添加给服务

// 获取远程服务代理           modelService service = (modelService)context.getBean("modelService");           //远程添加监听器,远程实现监听器           service.addCallback(new Callback() {public void msg_changed(String msg) {System.out.println("监听器1收到了新消息 :"+msg);}});           service.addCallback(new Callback() {public void msg_changed(String msg) {System.out.println("监听器2收到了新消息 :"+msg);}});           //远程调用方法来触发监听器           service.send_msg("new_msg");
查看消费者本地结果可以看到监听器方法被调用



4.事件通知

在远程方法被调用的时候,调用前、调用后、抛出异常时分别会发起三个事件。在消费者方可以定义一个通知类,在发起事件的时候通知类自动调用对应的方法
(1)提供者
提供者暴露一个参数返回值都是string的方法
package com.tyf.d_zk_provider;public class modelServiceImpl implements modelService {public String serviceTest(String data) {System.out.println("提供方调用 :"+data);return "提供方计算结果";}}
(2)消费者
定义事件通知接口、接口实现类
package com.tyf.d_zk_consumer;public interface Notify {//调用后public void onreturn(Object res,Object... args);//抛出异常时    public void onthrow(Throwable ex,Object... args);}<!--  分割线  -->package com.tyf.d_zk_consumer;class NotifyImpl implements Notify {    public void onreturn(Object res, Object... args) {System.out.println("返回值  :"+res);for(Object obj:args){System.out.println("参数  :"+obj);}}public void onthrow(Throwable ex, Object... args) {System.out.println("抛出的异常  :"+ex);for(Object obj:args){System.out.println("异常参数  :"+obj);}}}

消费者在引用服务时将通知类关联起来

    <!-- 通知类 -->    <bean id ="notify" class = "com.tyf.d_zk_consumer.NotifyImpl" />    <!-- 引用提供者接口 -->    <dubbo:reference id="modelService" interface="com.tyf.d_zk_provider.modelService" >        <dubbo:method name="serviceTest"               async="true"               onreturn = "notify.onreturn"               onthrow="notify.onthrow" />    </dubbo:reference>
其中async代表异步或同步、onreturn代表是否开启事件通知。两两组合有四种。这里设置为同步、开启事件通知。设置通知类的bean将它的两个方法和onreturn、onthrow关联起来
消费者远程调用
       // 获取远程服务代理           modelService service = (modelService)context.getBean("modelService");           // 调用           service.serviceTest("data");
调用成功会触发通知类的onreturn方法:







阅读全文
0 0