一、可以使用CompletableFuture返回类型
1.服务端定义接口:
package cn.edu.tju.tianda.dubbo.api;
import java.util.concurrent.CompletableFuture;
public interface AsyncService {
/**
* 同步调用方法
*/
String getWelcome(String param);
/**
* 异步调用方法
*/
CompletableFuture<String> asyncGetWelcome(String param);
}
2.服务端实现异步响应接口:
package cn.edu.tju.tianda.dubbo.service;
import cn.edu.tju.tianda.dubbo.api.AsyncService;
import org.apache.dubbo.config.annotation.DubboService;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
//@DubboService
public class AsyncServiceImpl implements AsyncService {
@Override
public String getWelcome(String param) {
return null;
}
@Override
public CompletableFuture<String> asyncGetWelcome(String param) {
// 建议为supplyAsync提供自定义线程池
return CompletableFuture.supplyAsync(() -> {
try {
// Do something
long time = ThreadLocalRandom.current().nextLong(1000);
Thread.sleep(time);
StringBuilder s = new StringBuilder();
s.append("AsyncService asyncInvoke param:").append(param).append(",sleep:").append(time);
return s.toString();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return null;
});
}
}
3.客户端调用异步响应接口
package cn.edu.tju.tianda.dubbo.consumer;
import cn.edu.tju.tianda.dubbo.api.AsyncService;
import cn.edu.tju.tianda.dubbo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component
public class AsyncConsumer implements CommandLineRunner {
@DubboReference()
private AsyncService asyncService;
@Override
public void run(String... args) throws Exception {
CompletableFuture<String> future = asyncService.asyncGetWelcome("amadeus");
future.whenComplete((v,t) -> {
System.out.println(v);
});
/* String result = future.get();
System.out.println("Receive async result ======> " + result);*/
}
}
二、使用dubbo提供的AsyncContext,只需要改变上边例子中的服务实现:
package cn.edu.tju.tianda.dubbo.service;
import cn.edu.tju.tianda.dubbo.api.AsyncService;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.AsyncContext;
import org.apache.dubbo.rpc.RpcContext;
import java.util.concurrent.CompletableFuture;
@DubboService
public class AsyncServiceImpl2 implements AsyncService {
@Override
public String getWelcome(String param) {
return null;
}
@Override
public CompletableFuture<String> asyncGetWelcome(String param) {
AsyncContext asyncContext = RpcContext.startAsync();
new Thread(new Runnable() {
@Override
public void run() {
asyncContext.signalContextSwitch();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 写回响应
asyncContext.write("Hay " + param + ", response from provider.");
}
}).start();
return null;
}
}
客户端异步调用代码:
package cn.edu.tju.tianda.dubbo.consumer;
import cn.edu.tju.tianda.dubbo.api.AsyncService;
import cn.edu.tju.tianda.dubbo.api.DemoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
@Component
public class AsyncConsumer2 implements CommandLineRunner {
@DubboReference()
private AsyncService asyncService;
@Override
public void run(String... args) throws Exception {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return asyncService.getWelcome(" amadeus liu");
});
future.whenComplete((v,t) -> {
System.out.println(v);
});
}
}