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. mogodbshell中数组对象查询修改方法

    在mongodb中,存在如下数据 { "_id" : ObjectId("59af55078a8fc5e51ff425de"), "title&quo ...

  2. 曹工说Tomcat1:从XML解析说起

    一.前言 第一次被人喊曹工,我相当诧异,那是有点久的事情了,楼主13年校招进华为,14年在东莞出差,给东莞移动的通信设备进行版本更新.他们那边的一个小伙子来接我的时候,这么叫我的,刚听到的时候,心里一 ...

  3. 【入门】WebRTC知识点概览 | 内有技术干货免费下载

    什么是WebRTC WebRTC 即Web Real-Time Communication(网页实时通信)的缩写,是一个支持网页浏览器之间进行实时数据传输(包括音频.视频.数据流)的技术.经过多年的发 ...

  4. spring cloud 系列第8篇 —— config+bus 分布式配置中心与配置热刷新 (F版本)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.config 简介 spring cloud config 分为服务端 ...

  5. BootStrap4.0Demo+轮播素材记录

    整理一些关于前端的东西: BootStrap4.0Demo: 官方DEMO:http://code.z01.com/v4/components/carousel.html 下午翻了点不错的轮播素材: ...

  6. Null作为参数的时候,Java编译器如何调用函数?

    public class TestNull { public void method(Object o){ System.out.println("Object Version") ...

  7. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

  8. shell遍历文件

    取文件每行的数据,需要按列取  可以 sed 加管道 使用 awk 取列 platform="list.txt" line=`grep -vc '^$' $platform` ; ...

  9. isinstance()函数判断数据类型

    判断是否是字符串 a = b = " print(isinstance(a,str)) print(isinstance(b,str)) False True 判断是否是列表 a = [,, ...

  10. 02_javaSE面试题:单例设计模式

    还记得很多年前,面试就让在白板上写个单例模式,当时技术渣渣,还写的是class A.面试官还说,你就不能写个Singleton. 面试题 编程题:写一个Singleton示例 解析 什么是Single ...