0. dubbo同步调用、异步调用和是否返回结果配置

(1)dubbo默认为同步调用,并且有返回结果。

(2)dubbo异步调用配置,设置 async="true",异步调用可以提高效率。

(3)dubbo默认是有返回结果,不需要返回,可以设置return="false",不需要返回值,可以减少等待结果时间。

1. 源码分析(dubbo版本:2.6.0)

dubbo自身底层调用是使用netty异步实现的,默认同步调用返回结果,是通过获取ResponseFuture,然后使用ReentrantLock的await使当前线程等待结果,设置返回的。下面是部分核心代码部分:

com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker.doInvoke(Invocation)

    @Override
protected Result doInvoke(final Invocation invocation) throws Throwable {
RpcInvocation inv = (RpcInvocation) invocation;
final String methodName = RpcUtils.getMethodName(invocation);
inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
inv.setAttachment(Constants.VERSION_KEY, version); ExchangeClient currentClient;
if (clients.length == 1) {
currentClient = clients[0];
} else {
currentClient = clients[index.getAndIncrement() % clients.length];
}
try {
// 获取是否异步配置async
boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
// 获取是否需要返回结果配置return
boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
// 获取超时配置timeout
int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
if (isOneway) {
// 不管是否异步,只要不需要返回结果,直接异步调用,设置结果为null
boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
currentClient.send(inv, isSent);
RpcContext.getContext().setFuture(null);
return new RpcResult();
} else if (isAsync) {
// 如果异步,并且需要返回结果,调用后设置结果future
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) {
throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
} catch (RemotingException e) {
throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
}
}

2. 实例

这里使用dubbo源码自带的例子

(1)在dubbo-demo-api中定义异步服务

package com.alibaba.dubbo.demo;

public interface AsyncDemoService {
String sayHello(String name);
}

(2)在dubbo-demo-provider中实现

package com.alibaba.dubbo.demo.provider;

import java.text.SimpleDateFormat;
import java.util.Date; import com.alibaba.dubbo.demo.AsyncDemoService;
import com.alibaba.dubbo.rpc.RpcContext; public class AsyncDemoServiceImpl implements AsyncDemoService{ @Override
public String sayHello(String name) {
System.out.println("[" + new SimpleDateFormat("HH:mm:ss").format(new Date()) + "] Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
return "Hello " + name + ", response form provider: " + RpcContext.getContext().getLocalAddress();
} }

(3)在dubbo-demo-provider.xml中配置服务信息

    <bean id="asyncDemoService" class="com.alibaba.dubbo.demo.provider.AsyncDemoServiceImpl"/>

    <dubbo:service interface="com.alibaba.dubbo.demo.AsyncDemoService" ref="asyncDemoService"/>

(4)在dubbo-demo-consumer.xml中配置调用服务信息,设置为异步调用async="true"

    <dubbo:reference id="asyncDemoService" check="false" interface="com.alibaba.dubbo.demo.AsyncDemoService">
<dubbo:method name="sayHello" async="true"/>
</dubbo:reference>

(5)在dubbo-demo-consumer的Consumer类中增加调用

        AsyncDemoService asyncDemoService = (AsyncDemoService) context.getBean("asyncDemoService");
asyncDemoService.sayHello("world");
// 通过 1.源码分析 中可以知道异步返回结果放到了RpcContext.getContext()中
Future<String> future = RpcContext.getContext().getFuture();

      try {
          String hello = future.get(1, TimeUnit.SECONDS);
          System.out.println(hello);
        } catch (InterruptedException e) {
          e.printStackTrace();
        } catch (ExecutionException e) {
          e.printStackTrace();
        } catch (TimeoutException e) {
          e.printStackTrace();
        }

(6)不需要返回结果,配置dubbo-demo-consumer.xml 中return="false",同步异步的调用方式一样的,很简单,只需要调用一下就可以继续其他操作,下面是异步的例子。

        AsyncDemoService asyncDemoService = (AsyncDemoService) context.getBean("asyncDemoService");
asyncDemoService.sayHello("world");

dubbo同步调用、异步调用和是否返回结果源码分析和实例的更多相关文章

  1. 【转载】Android异步消息处理机制详解及源码分析

    PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...

  2. dubbo注册服务IP解析异常及IP解析源码分析

    在使用dubbo注册服务时会遇到IP解析错误导致无法正常访问. 比如: 本机设置的IP为172.16.11.111, 但实际解析出来的是180.20.174.11 这样就导致这个Service永远也无 ...

  3. Android进阶——多线程系列之异步任务AsyncTask的使用与源码分析

    AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并主线程中更新UI,通过AsyncTask可以更加方便执行后台任务以及在主线程中访问UI ...

  4. dubbo负载均衡策略及对应源码分析

    在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用.我们还可以扩展自己的负责均衡策略,前提是你已经从一个小白变成了大牛,嘻嘻 1.Random LoadBalance 1 ...

  5. 源码分析Dubbo服务消费端启动流程

    通过前面文章详解,我们知道Dubbo服务消费者标签dubbo:reference最终会在Spring容器中创建一个对应的ReferenceBean实例,而ReferenceBean实现了Spring生 ...

  6. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class ...

  7. python 37 同步、异步调用

    目录 1. 阻塞与非阻塞 2. 同步与异步 2.1 异步调用 2.2 同步调用 2.3 异步调用回收的第一种方式 3. 异步调用+回调函数 3.1 requests模块 3.2 异步调用回收的第二种方 ...

  8. 20160711--C# 委托的三种调用示例(同步调用 异步调用 异步回调)【转载】

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 代码如下: public delegate int AddHandler(int a,int b); public class 加法类 { p ...

  9. 浅谈WebService开发二(同步与异步调用)转

    上文 <http://www.dotnetgeek.cn/xuexiwebservice1.html>已经跟大家说了,如果创建一个webservice和简单的调用,本文将注重webserv ...

随机推荐

  1. GCC链接库的一个坑:动态库存在却提示未定义动态库的函数

    背景 在GCC中已经指定链接库,然而编译时却提示动态库函数未定义! 测试出现的错误提示如下: [GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c /tmp/ ...

  2. springboot部署到tomcat

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 多点经验: 1.保证运行环境的jdk和开发环境一致,不然class文件无法被编译 2.保证tomcat和java的版本匹配 ...

  3. IM推送保障及网络优化详解(二):如何做长连接加推送组合方案

    对于移动APP来说,IM功能正变得越来越重要,它能够创建起人与人之间的连接.社交类产品中,用户与用户之间的沟通可以产生出更好的用户粘性. 在复杂的 Android 生态环境下,多种因素都会造成消息推送 ...

  4. HBase 学习之路(九)——HBase容灾与备份

    一.前言 本文主要介绍Hbase常用的三种简单的容灾备份方案,即CopyTable.Export/Import.Snapshot.分别介绍如下: 二.CopyTable 2.1 简介 CopyTabl ...

  5. chrome如何查看cookie

    以mac为例: 第一步:点击chrome的偏好设置 第二步:点击如下图所示的最下面的高级 第三步:点击内容设置,如下所示 第四步:点击cookie,就会出现查看所有cookie和网站数据

  6. php函数引用

    //在自定义函数中,前面加一个&符号,是对返回静态变量的引用 function &test(){ static $a; $a += 1; echo $a; return $a; } / ...

  7. c# 自己实现可迭代的容器

    在c#中我们经常使用到foreach语句来遍历容器,如数组,List,为什么使用foreach语句能够遍历一个这些容器呢,首先的一个前提是这些容器都实现了IEnumerable接口,通过IEnumer ...

  8. Python批量自动裁剪图片

    """用Pythonp批量裁剪图片""" from PIL import Image import matplotlib.pyplot as ...

  9. 浅说——树形DP

    啊!DP! 顾名思义,树形DP就是在树上所做的动态规划.我们一般所做的动态规划多是线性的,线性DP我们可以从前向后或从后向前两种方法,不妨类比一下,在树上我们同样可以有两种方法,从根向树叶或者从树叶向 ...

  10. java虚拟机-GC-GC算法

    在C/C++中是由程序员自己去申请.管理和释放内存的,因此没有GC的概念.而在Java中,专门有一个用于垃圾回收的后台线程来进行监控.扫描,自动将一些无用的内存进行释放.下面介绍几种常见的GC算法. ...