异步执行

Dubbo 服务提供方的异步执行

Provider端异步执行将阻塞的业务从Dubbo内部线程池切换到业务自定义线程,避免Dubbo线程池的过度占用,有助于避免不同服务间的互相影响。异步执行无异于节省资源或提升RPC响应性能,因为如果业务执行需要阻塞,则始终还是要有线程来负责执行。

注意

Provider 端异步执行和 Consumer 端异步调用是相互独立的,你可以任意正交组合两端配置

  • Consumer同步 - Provider同步
  • Consumer异步 - Provider同步
  • Consumer同步 - Provider异步
  • Consumer异步 - Provider异步

定义 CompletableFuture 签名的接口

服务接口定义:

  1. public interface AsyncService {
  2. CompletableFuture<String> sayHello(String name);
  3. }

服务实现:

  1. public class AsyncServiceImpl implements AsyncService {
  2. @Override
  3. public CompletableFuture<String> sayHello(String name) {
  4. RpcContext savedContext = RpcContext.getContext();
  5. // 建议为supplyAsync提供自定义线程池,避免使用JDK公用线程池
  6. return CompletableFuture.supplyAsync(() -> {
  7. System.out.println(savedContext.getAttachment("consumer-key1"));
  8. try {
  9. Thread.sleep(5000);
  10. } catch (InterruptedException e) {
  11. e.printStackTrace();
  12. }
  13. return "async response from provider.";
  14. });
  15. }
  16. }

通过 return CompletableFuture.supplyAsync() ,业务执行已从 Dubbo 线程切换到业务线程,避免了对 Dubbo 线程池的阻塞。

使用AsyncContext

Dubbo 提供了一个类似 Servlet 3.0 的异步接口AsyncContext,在没有 CompletableFuture 签名接口的情况下,也可以实现 Provider 端的异步执行。

服务接口定义:

  1. public interface AsyncService {
  2. String sayHello(String name);
  3. }

服务暴露,和普通服务完全一致:

  1. <bean id="asyncService" class="org.apache.dubbo.samples.governance.impl.AsyncServiceImpl"/>
  2. <dubbo:service interface="org.apache.dubbo.samples.governance.api.AsyncService" ref="asyncService"/>

服务实现:

  1. public class AsyncServiceImpl implements AsyncService {
  2. public String sayHello(String name) {
  3. final AsyncContext asyncContext = RpcContext.startAsync();
  4. new Thread(() -> {
  5. // 如果要使用上下文,则必须要放在第一句执行
  6. asyncContext.signalContextSwitch();
  7. try {
  8. Thread.sleep(500);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. // 写回响应
  13. asyncContext.write("Hello " + name + ", response from provider.");
  14. }).start();
  15. return null;
  16. }
  17. }

最后修改 September 21, 2021: Bug fix miss mialbox (#953) (57cf51b)