What’s the Dubbo Service Call Process? A 10‑Step Deep Dive
The article breaks down a complete Dubbo RPC invocation into ten precise steps—five on the consumer side and five on the provider side—explaining each core component such as Proxy, Filter, Cluster, LoadBalance, Protocol, and Transport, and addresses common interview follow‑up questions about clustering, load balancing, and sync vs async calls.
Dubbo Call Chain Overview
Consumer initialization – ReferenceConfig creates a service reference via ProxyFactory.
Consumer invocation – the proxy forwards the call to an Invoker and then through the consumer‑side Filter chain, handled by InvokerInvocationHandler.
Cluster fault‑tolerance – the request enters Cluster → Directory → Router. The default FailoverClusterInvoker retries twice (three attempts total).
Load balancing – LoadBalance selects one Invoker. The default algorithm is weighted Random.
Network send – Protocol → Exchanger → Transporter using DubboProtocol and NettyClient.
Network receive – Transporter → Exchanger → Protocol on the provider side with NettyServer and DubboProtocol.
Provider processing – provider‑side Filter chain → Invoker → ProxyFactory.
Actual execution – JavassistProxyFactory (or JDK proxy) uses reflection to invoke the local implementation.
Result return – the result is serialized and sent back through NettyServer.
Consumer receives – NettyClient matches the response by request ID, deserializes it, and returns it to the caller.
Consumer‑Side Details
Dubbo generates a dynamic proxy (Javassist by default) for the service interface. The proxy intercepts the method call, builds an Invocation object containing interface name, method name, parameter types and values, and passes it downstream.
@Service
public class OrderServiceImpl implements OrderService {
@DubboReference
private UserService userService; // actually a proxy object
public User getOrderUser(Long orderId) {
// looks like a local call, but is intercepted by the proxy
return userService.getUser(orderId);
}
}Built‑in consumer filters: ConsumerContextFilter – sets RpcContext local/remote address. MonitorFilter – records call count and latency, reports to monitoring. FutureFilter – handles async callback notifications.
Custom filters can be added for logging, tracing, rate limiting, etc.
Cluster and LoadBalance
After the filter chain, the request reaches the Cluster layer, which performs three sub‑steps:
Directory fetches the candidate provider list from the registry (e.g., Nacos, ZooKeeper) and keeps it up‑to‑date.
Router applies routing rules (e.g., same‑zone, gray release) to filter candidates, reducing the list size.
LoadBalance selects one provider based on the configured strategy; Random (weighted) is the default.
The selected provider is invoked via FailoverClusterInvoker, which retries twice on failure (three attempts total). The cluster strategy can be changed, e.g., <dubbo:reference cluster="failfast"/> for fast‑fail semantics.
Provider‑Side Details
NettyServerreceives the byte stream, decodes it with DubboProtocol into an Invocation object.
Provider‑side filter chain: ContextFilter – sets server‑side RpcContext. ExceptionFilter – prevents custom exceptions from being wrapped as RuntimeException. TimeoutFilter – logs timeout warnings. MonitorFilter – reports call statistics.
Finally, AbstractProxyInvoker uses reflection to invoke the local implementation and returns a CompletableFuture with the result.
public class AbstractProxyInvoker<T> implements Invoker<T> {
private final T proxy; // local implementation instance
private final Method method; // method to invoke
@Override
public Result invoke(Invocation invocation) {
Object value = method.invoke(proxy, invocation.getArguments());
return new CompletableFuture<>(value);
}
}The result is serialized, sent back through NettyServer, and the consumer’s NettyClient matches the response by request ID, deserializes it, and returns it to the business code.
Additional Topics
Fault‑tolerance strategies : default is Failover (2 retries). Failfast is recommended for write‑heavy scenarios to avoid duplicate submissions.
Load‑balance algorithms : Random (default), RoundRobin, LeastActive, ConsistentHash.
Sync vs. async : underlying Netty I/O is asynchronous, but Dubbo exposes a synchronous API (blocking get()) by default. Since Dubbo 2.7, asynchronous calls using CompletableFuture are supported.
Registry outage handling : the consumer caches the provider list locally, so calls continue to work even if the registry becomes unavailable.
Key Takeaway
Dubbo’s service invocation follows a ten‑step responsibility chain – five steps on the consumer side and five on the provider side – expressed as
Proxy → Filter → Cluster → LoadBalance → Protocol → Transport. The chain is transparent to business code, providing RPC with pluggable clustering, load balancing, and transport implementations.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Handbook
Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
