从dubbo的2.7.0版本,所有异步编程接口以CompletableFuture为基础。

基于NIO的非阻塞实现并行调用,服务消费方不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销教小。

简而言之,消费者通过异步调用,不用等待服务提供者返回结果就立即完成任务,待有结果之后再执行之前设定好的监听逻辑。

1、接口层修改:

 1 package com.yas.api;
 2 
 3 import java.util.concurrent.CompletableFuture;
 4 
 5 public interface SiteService {
 6     String getName(String name);
 7 
 8     //回调方法
 9     default String getName(String name,String key,SiteServiceListener siteServiceListener){
10         return null;
11     }
12 
13     //异步调用方法
14     default CompletableFuture<String> getNameAsync(String name){
15         return null;
16     }
17 }

 

2、提供方代码:

 1 package com.yas.serviceprovider.impl;
 2 
 3 import com.yas.api.SiteService;
 4 import org.apache.dubbo.config.annotation.Service;
 5 
 6 import java.util.concurrent.CompletableFuture;
 7 
 8 @Service(version = "async")
 9 public class AsyncSiteServiceImpl implements SiteService {
10     @Override
11     public String getName(String name) {
12         return "async:" + name;
13     }
14 
15     @Override
16     public CompletableFuture<String> getNameAsync(String name) {
17         System.out.println("异步调用");
18         return CompletableFuture.supplyAsync(() -> {
19             return getName(name);
20         });
21     }
22 }

 

3、消费方代码

 1 package com.yas.serviceconsumer.controller;
 2 
 3 import com.yas.api.SiteService;
 4 import org.apache.dubbo.config.annotation.Reference;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RequestParam;
 7 import org.springframework.web.bind.annotation.RestController;
 8 
 9 import java.util.concurrent.CompletableFuture;
10 
11 @RestController
12 public class SiteController {
13 
14     @Reference(version = "async")
15     SiteService asyncSiteService;
16 
17     @RequestMapping("/async")
18     public String getNameByAsync(@RequestParam("name") String name){
19         //调用异步方法
20         CompletableFuture<String> future = asyncSiteService.getNameAsync(name);
21 
22         //设置监听,非阻塞
23         future.whenComplete((v,e)->{
24             if(e!=null){
25                 e.printStackTrace();
26             }else{
27                 System.out.println("async result:"+v);
28             }
29         });
30         return "异步调用完成";
31     }
32 }

 

4、测试:

使用postman请求地址:http://localhost:8000/async?name=zhangsan

得到响应如下:

 

调用完毕后,消费者的控制台会打印:

 

这个调用是异步的,底层使用的是NIO。

 

posted on 2021-11-04 14:07  Sempron2800+  阅读(215)  评论(0编辑  收藏  举报