首页 > 其他分享 >Dubbo异步调用

Dubbo异步调用

时间:2023-08-24 18:33:52浏览次数:37  
标签:Dubbo 调用 异步 接口 CompletableFuture 线程

Dubbo异步调用

原文出处:https://www.cnblogs.com/weir110/p/17455749.html

一、前言

“异步”作为性能优化的利器之一,对于系统优化是一种常见思路;Dubbo天然的异步模式,不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。本文将针对Dubbo 异步使用展开介绍。

img

二、使用模式

Dubbo 异步调用

在 Dubbo 中服务调用方和服务提供方都支持异步调用,其调用模式可以组合为以下四种:

1.Consumer同步 - Provider同步
2.Consumer异步 - Provider同步
3.Consumer同步 - Provider异步
4.Consumer异步 - Provider异步

Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无异于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。

三、使用方式

3.1 使用CompletableFuture签名的接口

  1. 服务端-接口声明 CompletableFuture
public interface AsyncService {
    CompletableFuture<String> sayHello(String name);
}
  1. 服务端-接口实现:
public class AsyncServiceImpl implements AsyncService {
    @Override
    public CompletableFuture<String> sayHello(String name) {
        return CompletableFuture.supplyAsync(() -> {
            System.out.println(name);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "async response from provider.";
        });
    }
}

通过 return CompletableFuture.supplyAsync() ,业务执行已从Dubbo线程切换到业务线程,避免了对Dubbo线程池的阻塞。

  1. 客户端-接口引入
<dubbo:reference id="asyncService" timeout="10000" interface="com.alibaba.dubbo.samples.async.api.AsyncService"/>
  1. 客户端-接口调用
// 调用直接返回CompletableFuture
CompletableFuture<String> future = asyncService.sayHello("async call request");
// 增加回调
future.whenComplete((v, t) -> {
    if (t != null) {
        t.printStackTrace();
    } else {
        System.out.println("Response: " + v);
    }
});
// 早于结果输出
System.out.println("Executed before response return.");

3.2 使用AsyncContext

  1. 客户端-接口引入
<dubbo:reference id="asyncService" interface="org.apache.dubbo.samples.governance.api.AsyncService">
      <dubbo:method name="sayHello" async="true" />
</dubbo:reference>
  1. 客户端-接口调用
// 此调用会立即返回null
asyncService.sayHello("world");
// 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future
CompletableFuture<String> helloFuture = RpcContext.getServiceContext().getCompletableFuture();
// 为Future添加回调
helloFuture.whenComplete((retValue, exception) -> {
    if (exception == null) {
        System.out.println(retValue);
    } else {
        exception.printStackTrace();
    }
});

或者,也可以这样做异步调用

CompletableFuture<String> future = RpcContext.getServiceContext().asyncCall(
    () -> {
        asyncService.sayHello("oneway call request1");
    }
);

future.get();

四、发送模式

异步总是不等待返回,你也可以设置是否等待消息发出

  • sent="true" 等待消息发出,消息发送失败将抛出异常。
  • sent="false" 不等待消息发出,将消息放入 IO 队列,即刻返回。
<dubbo:method name="findFoo" async="true" sent="true" />

如果你只是想异步,完全忽略返回值,可以配置 return="false",以减少 Future 对象的创建和管理成本

<dubbo:method name="findFoo" async="true" return="false" />

img

参考

阅读文献

代码案例

https://gitee.com/will-we/dubbo-blog/tree/main/2-advanced/dubbo-async

标签:Dubbo,调用,异步,接口,CompletableFuture,线程
From: https://www.cnblogs.com/JaxYoun/p/17654896.html

相关文章

  • Apache Dubbo 和 Apache RocketMQ 邀您参与,ASF 亚洲峰会 5 张门票免费送
    今年,CommunityOverCodeAsia2023将是阿帕奇亚洲大会的首次线下会议,北京,8月18日至20日。会议将持续3天,设有17个论坛方向,共收集到150余个议题投稿,其中中文议题约110个,英文议题近40个。ApacheDubbo和ApacheRocketMQ邀请您来参会,点击阅读原文或扫描下方海报的二......
  • zbar:Qt调用zbar做条码识别
    需求:Qt开发的一个程序,妹子总是说需要条码识别功能,没办法,只能加上这个功能 zbar编译:https://gitee.com/vvvj/zbar-windows 主要代码:#include"zbar.h"usingnamespacezbar;voidheihei::tool_tiaoma(){//qDebug()<<"条码===begin=====";QImageimg;......
  • 架构:第七章:基于Dubbo+Zookeeper项目架构
    Dubbo:简单的介绍一下Dubbo?(Dubbo是什么)dubbo就是个服务调用的东东。为什么怎么说呢?因为Dubbo是由阿里开源的一个RPC分布式框架那么RPC是什么呢?就是不同的应用部署到不同的服务器上,应用之间想要调用没有办法直接调用,因为不在一个内存空间,需要通过网络通讯来调用,或者传达调......
  • Winform项目中出现 "已经可见的窗体不能显示为模式对话框。在调用 showDialog 之前应
    1问题描述最近做一个winform项目,启动程序弹出的加载进度窗体时,发生如标题所示的异常。2尝试debug根据异常提示,在进度窗体弹出前添加代码Visable=false;--未解决逐步debug调试发现Form弹框运行了2次,由此查出bug所在。由于我是用的单例模式,在Program.cs中运行的还是new......
  • 探索操作系统:内核、启动和系统调用的奥秘
    前言首先,对于有科班背景的读者,可以跳过本系列文章。这些文章的主要目的是通过简单易懂的汇总,帮助非科班出身的读者理解底层知识,进一步了解为什么在面试中会涉及这些底层问题。否则,某些概念将始终无法理解。这些计算机基础文章将为你打通知识的任督二脉,祝你在编程领域中取得成功!......
  • html调用音频文件
    在HTML中调用音频文件有多种方式,可以使用<audio>标签或JavaScript来实现。使用<audio>标签:<audio>标签是HTML5提供的用于嵌入音频的标签,可以通过指定音频文件的URL来调用音频文件。例如:<audiosrc="path/to/audio.mp3"controls></audio>在src属性中指定音频文件的路径,可......
  • html调用视频文件
    在HTML中调用视频文件有多种方式,可以使用<video>标签或JavaScript来实现。使用<video>标签:<video>标签是HTML5提供的用于嵌入视频的标签,可以通过指定视频文件的URL来调用视频文件。例如:<videosrc="path/to/video.mp4"controls></video>在src属性中指定视频文件的路径,可......
  • 网页图标文件获取并在html中调用
    获取网页图标文件有以下几种方式:自定义图标:可以使用设计工具(如Photoshop、Illustrator等)创建自定义的图标,并将其保存为图像文件(如PNG、JPEG等格式)。使用图标库:有许多免费或付费的图标库可供选择,如FontAwesome、MaterialIcons、Ionicons等。这些图标库提供了大量的矢量图......
  • 获取字体文件并在html中调用
    要获取字体文件,可以通过以下几种方式:使用系统字体:可以直接使用操作系统中已经安装的字体,无需额外获取字体文件。在CSS样式中使用字体名称即可,例如:body{font-family:Arial,sans-serif;}使用Web字体:Web字体是专门为网页设计的字体文件,可以通过网络获取。常见的Web字......
  • 编写JavaScript文件并在heml中调用
    编写JavaScript文件的基本步骤如下:创建一个新的文本文件,并将其保存为以.js为扩展名的文件,例如script.js。在JavaScript文件中编写JavaScript代码。可以编写函数、变量、条件语句、循环等JavaScript代码。例如:functiongreet(){console.log("Hello,World!");}var......