dubbo源码实践-protocol层-invoker理解
Posted alf_cee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dubbo源码实践-protocol层-invoker理解相关的知识,希望对你有一定的参考价值。
1概述
Invoker官方解释:
Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实
现,也可能是一个远程的实现,也可能一个集群实现。
1.1 Invoker接口
通过源码可知Invoker接口不是SPI。 可以调用invoke方法执行调用。
Invocation是参数,如:调用那个方法名称、参数的类型、参数的值是什么等信息。
1.2 Invoker的实现类
从下图展示了各个Invoker实现类的作用。
2 例子代码
2.1 调用本地的实现
想象一下应用场景:dubbo服务提供者会先把提供的功能封装到service中,然后配置到dubbo中(注解或xml文件),dubbo就可以调用到这些service了。
问题:各个service的名称和方法都不同、参数也不一致,能用一种通用的方式掉用各个service吗?
解决方法:dubbo使用Invoker本地的实现来解决这个问题。
dubbo提供了两种实现方式JdkProxyFactory和JavassistProxyFactory。
2.1.1 JdkProxyFactory实现方式
InvokerTest类代码
package org.example.dubbo.invoker;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory;
import org.example.test.protocol.AlfService;
import org.example.test.protocol.IAlfService;
/** 本地Invoker使用, 2022/12/29. */
public class InvokerTest
public static void main(String[] args)
//业务服务类
AlfService alfService = new AlfService();
//构造一个空的url
URLBuilder urlBuilder = new URLBuilder();
URL url = urlBuilder.build();
//构造Invocation对象
RpcInvocation rpcInvocation = new RpcInvocation();
rpcInvocation.setMethodName("sayHolle");//指定调用的方法名
Class<?>[] parameterTypes = new Class[1];//指定调用的方法的参数类型
parameterTypes[0] = String.class;
rpcInvocation.setParameterTypes(parameterTypes);
Object[] args1 = new Object[1];//指定调用的方法的参数
args1[0] = "alf";
rpcInvocation.setArguments(args1);
//创建ProxyFactory
ProxyFactory proxyFactory = new JdkProxyFactory();
//传入service实例,接口和URL获取Invoker实例
Invoker<IAlfService> invoker = proxyFactory.getInvoker(alfService, IAlfService.class, url);
//调用invoker实例
Result result = invoker.invoke(rpcInvocation);
//获取service方法返回值
Object value = result.getValue();
System.out.println(value);
AlfService类
package org.example.test.protocol;
/** 业务类 */
public class AlfService implements IAlfService
@Override
public String sayHolle(String hi)
System.out.println("AlfService call");
return "hi " + hi;
运行结果,调用了service。
实现原理分析
不管什么service,通过proxyFactory.getInvoker获取到响应的Invoker实例,然后使用统一的invoke(Invocation invocation)方法来调用service。
JdkProxyFactory中的实现方式是通过java的反射实现的上述功能。
2.1.2 JavassistProxyFactory实现方式
只要把上面的代码替换成ProxyFactory proxyFactory = new JavassistProxyFactory(); 即可。
运行结果是一样的。
可以知道方式是通过javassist动态产生的一个Wrapper类的实现,然后编译、加载到JVM中。
产生的Wrapper实现的invokeMethod方法如下:
dubbo的默认实现是JavassistProxyFactory。因为性能更好。
2.2 远程调用
必须得有服务端才运行。这里就不演示了。参考DubboInvoker类实现。
下一篇会有例子。
2.3 集群的调用
集群的Invoker的继承关系如下图。
通过ClusterInvoker类的注释可以看到:
This is the final Invoker type referenced by the RPC proxy on Consumer side.
客户端使用该ClusterInvoker,并且是最外层的Invoker。
A ClusterInvoker holds a group of normal invokers, stored in a Directory, mapping to one Registry.
一个ClusterInvoker通过Directory持有一组普通的Invoker,Directory同时会对应一个注册(参考RegistryDirectory类)。
The ClusterInvoker implementation usually provides LB or HA policies, like FailoverClusterInvoker.
ClusterInvoker提供LB或者HA的功能,如FailoverClusterInvoker类。
In multi-registry subscription scenario, the final ClusterInvoker will referr to several sub ClusterInvokers, with each sub ClusterInvoker representing one Registry. Take ZoneAwareClusterInvoker as an example, it is specially customized for multi-registry use cases: first, pick up one ClusterInvoker, then do LB inside the chose Cluster。
在多注册中心订阅的场景下,一个最外层ClusterInvoker内部可以包含多个子ClusterInvoker,每个子ClusterInvoker代表的一个注册中心。可以参考ZoneAwareClusterInvoker类。
具体的例子请见下一篇文章。
2.4 AsyncToSyncInvoker类异步转同步
This class will work as a wrapper wrapping outside of each protocol invoker.
一个包装类,套在protocol invoker外面。
客户端调用服务端代码时应该是异步的(通过protocol invoker调用的),客户端可以在这个protocol invoker外面套一个AsyncToSyncInvoker,这样就转换到同步了,简化了代码的开发。
3 官方架构图中的Invoker
最开始看这张架构图,对里面3处Invoker不是很理解,现在终于清楚了。
1处:处理集群的Invoker,对外是一个Invoker,内部使用负载均衡等方法来选择一个Invoker(调用远程服务)来调用。
2 处:调用远程的Invoker。
3 处:服务端包装业务service的Invoker。
其实dubbo是一个RPC框架,要解决的就是客户端程序调用服务端程序。
服务端:用Invoker来封装业务service;
客户端:用Invoker来封装远程调用,用Invoker来封装集群。
顺便感叹一下,这个架构图画的真牛!!!
以上是关于dubbo源码实践-protocol层-invoker理解的主要内容,如果未能解决你的问题,请参考以下文章