文章目录
-
-
- 一、Cluster层
- 二、Protocol 层
-
- 1.ConsumerContextFilter 的invoke 方法
- 2.FutureFilter 的invoke 方法
- 3.MonitorFilter中的invoke方法
- 4.DubboInvoker中invoke方法
-
消费端代码示例(参考incubator-dubbo源码中dubbo-demo模块):
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
context.start();
DemoService demoService = (DemoService) context.getBean("demoService”);
// 调用远程方法
String hello = demoService.sayHello("world");
System.out.println(hello);
以dubbo分层概念来理解消费端调用过程:

服务端启动后,消费端引用服务端的接口类会生成一个代理类,即生成InvokerInvocationHandler(invoker)对象实例,所以在调用的时候,会直接调用 InvokerInvocationHandler 的 invoke 方法,
一、Cluster层
Cluster层作用:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
根据 https://blog.csdn.net/zhuqiuhui/article/details/84075521 分析知这里的 invoker 是 MockClusterInvoker 实例,即会调用 MockClusterInvoker 的invoke方法,该方法首先判断directory中的url是否含有mock值的设定,若没有设置默认值false。这里的directory中的url的变量是:
Debug,如下:
其中 this.invoker变量值如下:
上面会调用FailOverClusterInvoker.invoke(),即会调用其父类AbstractClusterInvoker.invoke()的方法。如下:
Debug-1:
Debug-1 分成以下几个过程:
1. 检查RPC Cluster invoker中要执行的接口是否被销毁,若销毁,则抛出异常。
2. 在调用提供者之前,会获取当前线程临时变量里的RpcContext对象,再将RpcContext对象里的参数设置到Invocation对象。
RpcContext 是一个临时状态持有者,每当发请求或者收到请求的时候RpcContext都会发生变化。例如A调用B,然后B调用C,在服务B中,在B调用C之前,RpcContext保存了A调用B的参数。当B调用C的时候,RpcContext保存了B调用C的参数。从源码上看RpcContext对象是绑定在线程临时变量LOCAL上,所以可以通过线程临时变量来获取到RpcContext的相关参数值。
3. 列出所有的Invoker
这里可以看到 directory实例是 RegistryDirectory 的实例,会调用其父类的list方法,即如下:
上面走到RegistryDirectory的doList方法中,其中RegistryDirectory是在消费端服务启动过程中自动会生成RegistryDirectory实例,对应的属性也初始化完成了,即在消费端启动过程时,把方法和对应的invoker关系存放到了RegistryDirectory中的methodInvokerMap属性中(参考:https://blog.csdn.net/zhuqiuhui/article/details/84075521),所以这里,如下:
其中返回的 invokers 列表如上面的变量。
4. 获取方法上配置的负载均衡策略,若没有配置,选择默认的策略
常用的配置方法如下:
<dubbo:reference interloadbalance="roundrobin"/>
这里返回的 loadbalance 的实例是 RandomLoadBalance 的实例。
5. 幂等操作,即在异步操作中会默认加上invocation ID,不作分析
6. 方法调用
会走到 FailOverClusterInvoker 中的 doInvoke 方法中,即:
该方法首先使用负载均衡策略选择合适的invoker(不再分析),然后再进行invoker调用,其中invoker变量如下:
上面变量的第一行可以看出 invoker 实例是InvokerDelegate实例对象,调用其invoke方法会走到InvokerWrapper的invoke方法,由于InvokerDelegate实例对象中的invoker内部属性是 Invoker 接口的匿名实现,其泛型是ProtocolFilterWrapper类,即如上图中的”[email protected]”,所以会调用”[email protected]”实例invoke方法,看其内部实现:
private static <T> Invoker<T> buildInvokerChain(final Invoker<T> invoker, String key, String group) {
Invoker<T> last = invoker;
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
if (!filters.isEmpty()) {
for (int i = filters.size() - 1; i >= 0; i--) {
final Filter filter = filters.get(i);
final Invoker<T> next = last;
last = new Invoker<T>() {
@Override
public Class<T> getInterface() {
return invoker.getInterface();
}
@Override
public URL getUrl() {
return invoker.getUrl();
}
@Override
public boolean isAvailable() {
return invoker.isAvailable();
}
@Override
public Result invoke(Invocation invocation) throws RpcException {
return filter.invoke(next, invocation);
}
@Override
public void destroy() {
invoker.destroy();
}
@Override
public String toString() {
return invoker.toString();
}
};
}
}
return last;
}
调用的是filter的invoke方法(其中的filter实例是ConsumerContextFilter实例),首先会调用 ConsumerContextFilter 的 invoke 方法,在ConsumerContextFilter 的 invoke 方法中再调用 FutureFilter 的invoke方法,最后在 FutureFilter 的invoke方法中调用 MonitorFilter 的 invoke 方法,MonitorFilter 的 invoke 方法中会调用DubboInvoker 的invoke方法。
二、Protocol 层
Protocol层作用:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
1.ConsumerContextFilter 的invoke 方法
这里首先对 RpcContext 进行信息设置,其后清空sever上下文,再对调用后的结果进行后处理(即postProcessResult方法,主要设置一些要传递的参数),在finally中清空了传递的参数(目的为下一次调用做准备)。postProcessResult参数中的invoker调用invoke方法会继续调用下一个filter中的invoke方法,即FutureFilter中的invoke方法。从上面过程可以看出主要对 RpcContext 内容进行设置。
2.FutureFilter 的invoke 方法
主要做一些异步回调工作,其中 invoker.invoke方法会调用MonitorFilter中的invoke方法
3.MonitorFilter中的invoke方法
MonitorFilter会做下监控的处理。会调用 DubboInvoker中invoke方法。
4.DubboInvoker中invoke方法
走完上述方法就完成整个方法的调用过程。