dubbo中的异步调用

/ Dubbo / 没有评论 / 491浏览

有时我们在使用dubbo调用服务时,为了提供服务的调用效率,我们可以使用dubbo中的异步调用,dubbo中的异步调用底层使用的是NIO非阻塞方式实现,所以相比多线程开销要小。


因为dubbo中的异步调用是在服务调用方配置的,所以下面我们只看一下服务调用方的代码,而服务提供方不需要做任何改动。

consumer.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 调用方信息-->
    <dubbo:application name="jilinwula"/>

    <!-- 使用zookeeper查找服务地址 -->
    <dubbo:registry address="127.0.0.1:2181" protocol="zookeeper"/>

    <!-- Dubbo自动生成远程服务代理 -->

    <dubbo:reference id="helloWorld" interface="com.jilinwula.api.UserInfoService" async="true"/>

</beans>

我们只添加了async参数,当参数为true时表示异步调用。

Consumer:

/**
 * 服务调用方
 */
public class Consumer {

  public static void main(String[] args) throws Exception {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
        new String[]{"consumer.xml"});
    context.start();

    UserInfoService userInfoService = context.getBean("helloWorld", UserInfoService.class);

    System.out.println(userInfoService.getUserInfo("吉林乌拉"));

  }
}

因为是异步调用时,所以我们直接调用服务方法时,会立即返回null。

2018-08-04 21:56:07:719 INFO [ProductBossService,com.alibaba.dubbo.config.ReferenceConfig,425]:  [DUBBO] Refer dubbo service com.jilinwula.api.UserInfoService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=jilinwula&async=true&check=false&dubbo=2.6.0&generic=false&interface=com.jilinwula.api.UserInfoService&methods=getUserInfo&pid=2913&register.ip=192.168.0.4&remote.timestamp=1533390872832&side=consumer&timestamp=1533390966728, dubbo version: 2.6.0, current host: 192.168.0.4
null
2018-08-04 21:56:07:950 INFO [ProductBossService,com.alibaba.dubbo.config.AbstractConfig$1,80]:  [DUBBO] Run shutdown hook now., dubbo version: 2.6.0, current host: 192.168.0.4

如果我们想在获取到异步调用的结果,那我们则要需要下面的方式:

/**
 * 服务调用方
 */
public class Consumer {

  public static void main(String[] args) throws Exception {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
        new String[]{"consumer.xml"});
    context.start();

    UserInfoService userInfoService = context.getBean("helloWorld", UserInfoService.class);

    System.out.println(userInfoService.getUserInfo("吉林乌拉"));

    Future<UserInfoService> future = RpcContext.getContext().getFuture();

    System.out.println(future.get());

  }
}
2018-08-04 21:57:35:640 INFO [ProductBossService,com.alibaba.dubbo.config.ReferenceConfig,425]:  [DUBBO] Refer dubbo service com.jilinwula.api.UserInfoService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=jilinwula&async=true&check=false&dubbo=2.6.0&generic=false&interface=com.jilinwula.api.UserInfoService&methods=getUserInfo&pid=2920&register.ip=192.168.0.4&remote.timestamp=1533390872832&side=consumer&timestamp=1533391054529, dubbo version: 2.6.0, current host: 192.168.0.4
null
UserInfo{username='吉林乌拉', password='jilinwula'}
2018-08-04 21:57:35:846 INFO [ProductBossService,com.alibaba.dubbo.config.AbstractConfig$1,80]:  [DUBBO] Run shutdown hook now., dubbo version: 2.6.0, current host: 192.168.0.4

这里有一点要注意,因为是异步调用,所以在执行future.get()方法时,如果服务端此时还没有返回的话,那么客户端此时会阻塞。

有进我们只想异步调用服务,而不需要任何的返回结果,如日志记录等。那我们可以设置参数return="false",以减少Futrue对象的创建和管理成本。当我们设置该return为false时我们也就无法获取服务端方法的返回值了,如果我们继续调用future.get()方法时,dubbo会抛出空指针异常。

2018-08-04 22:27:26:391 INFO [ProductBossService,com.alibaba.dubbo.config.ReferenceConfig,425]:  [DUBBO] Refer dubbo service com.jilinwula.api.UserInfoService from url zookeeper://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?anyhost=true&application=jilinwula&check=false&dubbo=2.6.0&generic=false&getUserInfo.async=true&getUserInfo.return=false&interface=com.jilinwula.api.UserInfoService&methods=getUserInfo&pid=3042&register.ip=192.168.0.4&remote.timestamp=1533392826357&side=consumer&timestamp=1533392845258, dubbo version: 2.6.0, current host: 192.168.0.4
Exception in thread "main" java.lang.NullPointerException
	at com.jilinwula.consumer.Consumer.main(Consumer.java:25)
null
2018-08-04 22:27:26:608 INFO [ProductBossService,com.alibaba.dubbo.config.AbstractConfig$1,80]:  [DUBBO] Run shutdown hook now., dubbo version: 2.6.0, current host: 192.168.0.4