从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。