dubbo默认使用同步的方式调用。但在有些特殊的场景下,我们可能希望异步调用dubbo接口,从而避免不必要的等待时间,这时候我们就需要用到异步。那么dubbo的异步是如何实现的呢?下面就来看看这个问题
异步方法配置:

<dubbo:reference cache="lru" id="demoService" interface="com.ping.chen.dubbo.service.DemoService" timeout="5000"><dubbo:method name="sayHello" async="true"/>
</dubbo:reference>

底层的异步处理实现在DubboInvoker的doInvoke方法中,源码如下:

protected Result doInvoke(final Invocation invocation) throws Throwable {RpcInvocation inv = (RpcInvocation) invocation;忽略Attachment设置。。。try {// 是否异步执行boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);//是否单向执行int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);//接口超时时间,默认1秒if (isOneway) {boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);currentClient.send(inv, isSent);RpcContext.getContext().setFuture(null);return new RpcResult();} else if (isAsync) {//异步ResponseFuture future = currentClient.request(inv, timeout);RpcContext.getContext().setFuture(new FutureAdapter<Object>(future));return new RpcResult();} else {RpcContext.getContext().setFuture(null);return (Result) currentClient.request(inv, timeout).get();}} catch (TimeoutException e) {//异常处理。。。}
}

可以看到,如果异步执行,会直接返回一个空的RpcResult,然后用户如果需要异步执行结果,可以从RpcContext中的Future中去获取,直接用RpcContext.getContext().getFuture().get();就可以获取到执行结果。那么RpcContext是如何保证当前线程可以拿到执行结果呢?答案是ThreadLocal。我们来看看RpcContext源码如下:

public class RpcContext {private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() {@Overrideprotected RpcContext initialValue() {return new RpcContext();}};public static RpcContext getContext() {return LOCAL.get();}。。。。。。
}

可以看到RpcContext 内部是使用ThreadLocal来实现的。

异步可能遇到的坑

上面这种配置有一个坑,可能你会像下面这样使用异步:

@RestController
public class DemoController {@Reference(timeout = 5000)DemoProvider demoProvider;@RequestMapping("/demo")public void demo() throws ExecutionException, InterruptedException {demoProvider.sayHello("world");System.out.println(">>>>>>>>>>" + RpcContext.getContext().getFuture().get());}
}

然后请求demo接口的时候,很不幸,你将会收到一个NullPointException,这因为我们只在消费者端配置了异步执行,但服务端执行的时候是同步的,所以我们从RpcContext中获取到的Future是空的,正确的异步配置应该是:
直接去掉消费者端的

<dubbo:method name="sayHello" async="true"/>

配置,然后在服务提供者端做如下配置:

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="com.ping.chen.dubbo.provider.DemoProvider" ref="demoProvider" ><dubbo:method name="sayHello" async="true"/>
</dubbo:service>

如此,便可以实现异步了

转载于:https://www.cnblogs.com/canmeng-cn/p/10554625.html

dubbo入门之异步调用相关推荐

  1. Dubbo 同步、异步调用的几种方式

    我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制:基于这种机制,Dubbo 实现了以下几种调用方式: 同步调用 异步调用 参数回调 事件通知 同步调用 同 ...

  2. 基于dubbo实现异步调用

    1.前言 Java中常见的实现异步调用的方式: 1.ThreadPool 2.CompletableFuture 3.MQ 4.BlockingQueue 5.Fork/Join 那么作为一款优秀的R ...

  3. Dubbo的异步调用

    文章目录 dubbo异步调用 2.6版本中dubbo异步调用的实现 2.7版本dubbo 客户端Consumer异步调用 使用CompletableFuture签名的接口 1.调用远程服务: 2. 使 ...

  4. delphi 异步 调用 带参数_Dubbo 关于同步/异步调用的几种方式

    我们知道,Dubbo 缺省协议采用单一长连接,底层实现是 Netty 的 NIO 异步通讯机制:基于这种机制,Dubbo 实现了以下几种调用方式: 同步调用 异步调用 参数回调 事件通知 同步调用 同 ...

  5. dubbo异步调用传递性解决方法

    2019独角兽企业重金招聘Python工程师标准>>> 解决dubbo异步调用传递性: RpcContext.getContext().setAttachment(Constants ...

  6. 限时购校验小工具dubbo异步调用实现限

    本文来自网易云社区 作者:张伟 背景 限时购是网易考拉目前比较常用的促销形式,但是前期创建一个限时购活动时需要各个BU按照指定的Excel格式进行选品提报,为了保证提报数据准确,运营需要人肉校验很多信 ...

  7. Dubbo异步调用实现

    具体原理和介绍参看dubbo官方文档: http://dubbo.apache.org/zh-cn/docs/user/demos/async-call.html 1. 当使用异步调用时建议要和原有a ...

  8. dubbo入门--Hello World

    Dubbo入门--Hello World 转载自:http://blog.csdn.net/hanmov/article/details/66973957?locationNum=2&fps= ...

  9. Spring Boot 中使用@Async实现异步调用,加速任务执行!

    欢迎关注方志朋的博客,回复"666"获面试宝典 什么是"异步调用"?"异步调用"对应的是"同步调用",同步调用指程序按照 ...

最新文章

  1. R语言使用unzip函数解压压缩文件(Extract or List Zip Archives)
  2. html语言把字变大,css怎么让字体变大?
  3. 《Linux内核设计与实现》读书笔记(十五)- 进程地址空间(kernel 2.6.32.60)
  4. 跟我学Java(配光盘)(跟我学)
  5. C\C++不经意间留下的知识空白------宏
  6. 物联网思维导图_物联网将如何改变我们的思维方式
  7. 100层楼扔2个鸡蛋、3个鸡蛋……
  8. mysql hash切分_轻松优化MySQL-之数据库切分1
  9. 赛门铁克发布第21期《互联网安全威胁报告》 揭示当前更为严峻的网络威胁现状...
  10. posix and system V IPC
  11. 地图Web服务API接口——搜索POI(以高德地图为例)
  12. 微信H5支付跳转问题
  13. 互联网服务器使用ipset 和iptables禁止国外IP访问
  14. Selenium无法定位元素的九种解决方案
  15. 智遥工作代理问题解析
  16. HTML5在线摄像头应用
  17. unity3D-learning:UI背包系统
  18. AtCoder Beginner Contest 126
  19. html页面中引入script标签的src的写法,/与//的区别
  20. 《Occlusion Aware Facial Expression RecognitionUsing CNN With Attention Mechanism》论文阅读(2019TIP)

热门文章

  1. B 站崩了,总结下「高可用」和「异地多活」
  2. WatchOS开发教程之四: Watch与 iPhone的通信和数据共享
  3. Excel中vlookup模糊查找的妙用(模糊匹配)
  4. 选择排序(升序排列)
  5. codeMirror使用记录
  6. 删除ubuntu自带软件 及 WPS 安装(转)WPS字体已备份
  7. 利用ST MCU内部基准参考电压监测电源电压及其它
  8. 面试中经常被问到Java引用类型原理,带你深入剖析
  9. 如何区分b ,B,KB,MB,GB?
  10. C++-STL(1)-Vector-随机数(randon、default_random_engine)