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. 图片(img标签)的onerror事件,你有用过嘛?
  2. php拓展板块 按需开启,php如何按需加载方式来增加程序的灵活度
  3. mysql利用触发器删除数据库_[数据库]mysql 触发器的创建 修改 删除
  4. Struts2的Stack Context和ValueStack
  5. SPOJ.TLE - Time Limit Exceeded(DP 高维前缀和)
  6. Universal-Image-Loader解析(二)——DisplayImageOptions的详细配置与简单的图片加载...
  7. 函数模板(参考《C++ Templates 英文版第二版》)
  8. 倒计时 1 天 | 2019 中国大数据技术大会(BDTC)报名通道即将关闭(附参会提醒)...
  9. ORA-00911:无效字符 错误及解决
  10. 社区团购到底有什么魔力
  11. 重置Mysql自增列的开始序号
  12. android:视频录制编写代码一直报非法状态错误,很多时候定位在setVideoEncoder和setAudioEncoder...
  13. 使用python解决算法和数据结构--使用栈实现进制转换
  14. androidStudio 中使用矢量图
  15. thingworx ADO安装
  16. debian7 软件源更新
  17. pandas判断标称型和数值型特征数据
  18. 前端开发规范和开发文档的书写规范
  19. Grunt搭建自动化web前端开发环境--完整流程
  20. volatile作用

热门文章

  1. PADS9.5—layout中导入.asc文件时遇到的问题
  2. 微软skype收购案
  3. 平平无奇的营销小天才——ChatGPT
  4. Qt设置按钮背景图片
  5. Vue:前端体系与前后端分离
  6. 尚硅谷todolist案例
  7. python爬取问卷星内容,Python 问卷星自动填写 爬虫
  8. 终于有人把“内卷”和“囚徒困境”讲明白了!
  9. 使用二手书App的心得
  10. nlp-知识图谱简介