Asynchronous Calls
Dubbo not only provides traditional synchronous blocking call methods but also supports efficient asynchronous call patterns.
Asynchronous Call Implementation
Service Definition
public interface GreetingService {
String sayHello(String name, int timeToWait);
}
Consumer Configuration
<dubbo:reference id="greetingService" interface="com.example.GreetingService">
<dubbo:method name="sayHello" async="true" />
</dubbo:reference>
Consumer Call Example
// Initiate asynchronous call
greetingService.sayHello("world", 1000);
// Returns null immediately, actual call executes in background
System.out.println("Call returns immediately, continue executing other operations...");
// Get Future object from RpcContext
Future<String> future = RpcContext.getContext().getFuture();
// Wait and get result
String result = future.get(1500, TimeUnit.MILLISECONDS);
Notes
- Timeout Control: Dubbo’s default async call timeout is 1000ms
- Future Acquisition: Must obtain Future object in the same thread that initiated the call
- Exception Handling: Asynchronous calls need to check execution status and exceptions through Future
Thread Pool
Existing Thread Pool Implementations
1. Fixed size thread pool (fix)
- This is the default thread pool implementation used by Dubbo
- Creates 200 worker threads by default with no waiting queue
- Thread count is fixed and will not dynamically increase or decrease
2. Cached thread pool (cache)
- Thread count is not fixed and will be dynamically created based on demand
- Idle threads will be recycled (default after 60 seconds)
- Theoretically can infinitely expand thread count
Configuration Example
<dubbo:protocol name="dubbo" threadpool="fixed" threads="200"/>
Custom Thread Pool Solution
public class WzkWatchingThreadPool extends FixedThreadPool implements Runnable {
private static final double ALARM_PERCENT = 0.9;
private final Map<URL, ThreadPoolExecutor> THREADS_POOLS = new ConcurrentHashMap<>();
@Override
public Executor getExecutor(URL url) {
final Executor executor = super.getExecutor(url);
if (executor instanceof ThreadPoolExecutor) {
THREADS_POOLS.put(url, (ThreadPoolExecutor) executor);
}
return executor;
}
@Override
public void run() {
// Monitor thread pool usage
}
}
SPI Declaration
File META-INF/dubbo/org.apache.dubbo.common.threadpool.ThreadPool
wzkWatching=icu.wzk.pool.WzkWatchingThreadPool
Configuration Usage
dubbo.provider.threadpool=wzkWatching
Best Practices
- Set independent thread pools for different businesses
- Select appropriate thread pool type based on business characteristics
- Establish a comprehensive monitoring and alerting system
- Regularly perform pressure tests to evaluate thread pool capacity