Asynchronous execution

Asynchronous execution of Dubbo service provider

This document is no longer maintained. You are currently viewing a snapshot version. If you want to see the latest version of the documentation, see Latest Version.

The asynchronous execution of the provider side switches the blocked business from Dubbo’s internal thread pool to the business-defined thread, avoiding excessive occupation of the Dubbo thread pool, and helping to avoid the mutual influence between different services. Asynchronous execution is tantamount to saving resources or improving RPC response performance, because if business execution needs to be blocked, there is always a thread to be responsible for execution.

Define the interface of CompletableFuture signature

Service interface definition:

public interface AsyncService {
    CompletableFuture<String> sayHello(String name);
}

Service implementation:

public class AsyncServiceImpl implements AsyncService {
    @Override
    public CompletableFuture<String> sayHello(String name) {
        RpcContext savedContext = RpcContext. getContext();
        // It is recommended to provide a custom thread pool for supplyAsync and avoid using the JDK public thread pool
        return CompletableFuture. supplyAsync(() -> {
            System.out.println(savedContext.getAttachment("consumer-key1"));
            try {
                Thread. sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "async response from provider.";
        });
    }
}

Through return CompletableFuture.supplyAsync(), the business execution has been switched from the Dubbo thread to the business thread, avoiding the blocking of the Dubbo thread pool.

Using AsyncContext

Dubbo provides an asynchronous interface AsyncContext similar to Servlet 3.0, which can also implement asynchronous execution on the Provider side without the CompletableFuture signature interface.

Service interface definition:

public interface AsyncService {
    String sayHello(String name);
}

Service exposure is exactly the same as ordinary services:

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

Service implementation:

public class AsyncServiceImpl implements AsyncService {
    public String sayHello(String name) {
        final AsyncContext asyncContext = RpcContext. startAsync();
        new Thread(() -> {
            // If you want to use the context, it must be executed in the first sentence
            asyncContext.signalContextSwitch();
            try {
                Thread. sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // write back the response
            asyncContext.write("Hello " + name + ", response from provider.");
        }).start();
        return null;
    }
}

Last modified January 2, 2023: Enhance en docs (#1798) (95a9f4f6c1)