共计 3197 个字符,预计需要花费 8 分钟才能阅读完成。
本文聊聊 dubbo 的最外围模型 Invoker
,在 dubbo 官网上是这么形容的:
Invoker 是实体域,它是 Dubbo 的外围模型,其它模型都向它聚拢,或转换成它,它代表一个可执行体,可向它发动 invoke 调用,它有可能是一个本地的实现,也可能是一个近程的实现,也可能一个集群实现。
Invoker
是一个执行体的形象,执行体能够是本地的也能够是近程的,能够是集群的也能够是单实例的,能够是实在的业务实现也能够是假装的本地实现,能够是 dubbo 协定也能够是其余协定,他的形象等级十分高,不关怀具体实现只关怀输出和输入。
先看下 Invoker
的接口申明:
public interface Invoker<T> extends Node {
// 这个 Invoker 可执行体是承载的那个接口,如 DemoService
Class<T> getInterface();
// 最外围的调用模型,传入一个 Invocation 会话域返回一个带有后果的实体
Result invoke(Invocation invocation) throws RpcException;
}
另一个外围模型 Protocol
负责管理 Invoker
的生命周期,它的 API 都是围绕着 Invoker
进行的,看看它的接口申明:
public interface Protocol {
// 服务端裸露端口
int getDefaultPort();
// 服务端裸露形式
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
// 客户端援用形式
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
// 销毁形式,服务端、客户端都应用
void destroy();}
Invoker
是 dubbo 的灵魂,服务端和客户端都是围绕这个实体来运行,不同的 Invoker
承载不同的调用形式。
从他们的应用场景来看能够分为以下几类:
- 服务端代理类
其实现类次要以 AbstractProxyInvoker
为父类,次要有:
Anonymous in getInvoker() in JavassistProxyFactory
Anonymous in getInvoker() in JdkProxyFactory
ByteBuddyProxyInvoker // 3.x 新增
他们的次要作用是在服务端将近程调用关联到本地具体的执行业务办法上,也就是本地业务接口的代理,这也是它命名为 proxyInvoker 的起因,因为框架自身无奈当时晓得业务接口所以这里将业务接口用字节码编译技术用 Wrapper 进行包装,最初通过 Wrapper#invokeMethod
调用实在的实现。
这里以源码 demo 中的 DemoService
实现类为例看下生成的的 invokeMethod
实现:
public class Wrapper0 extends Wrapper implements ClassGenerator.DC {public Object invokeMethod(Object var1, String var2, Class[] var3, Object[] var4) throws InvocationTargetException {
DemoService var5;
try {var5 = (DemoService) var1;
} catch (Throwable var8) {throw new IllegalArgumentException(var8);
}
try {
// 依据接口和办法名找到对应的业务实现进行实在调用
if ("sayHello".equals(var2) && var3.length == 1) {return var5.sayHello((String) var4[0]);
}
} catch (Throwable var9) {throw new InvocationTargetException(var9);
}
throw new NoSuchMethodException("Not found method \"" + var2 + "\" in class com.alibaba.dubbo.demo.DemoService.");
}
}
在服务端生成 Wrapper
类后框架层不会间接调用业务实现类,而是通过 Wrapper
类委托给实在的实现类,这样就实现了和业务解耦。
- 单个实例近程调用类
这些类大都以 AbstractInvoker
为基类,次要包含以下几个:
Anonymous in refer() in MemcachedProtocol
Anonymous in refer() in RedisProtocol
DubboInvoker
InjvmInvoker
ThriftInvoker
GrpcInvoker 2.7.x 新增
TripleInvoker 3.x 新增
MockInvoker 未继承 AbstractInvoker
这些大都是具体的协定的近程调用的实现,也就是 Protocol#refer
进去的对象,只针对单个服务端实例,集群模式下再应用集群 ClusterInvoker
进行加强。
其外部实现大都是通过通过 socket 链接将本地调用进行编码发送到近程,典型如 DubboInvoker
,也有非凡的如 InjvmInvoker
是 jvm 内本地间接调用而不必通过 socket。
MockInvoker
是一个比拟非凡的实现,它并不和某个协定捆绑,他次要用来实现本地假装,次要在 MockClusterInvoker
中和服务降级一起应用。
- 集群近程调用类
这些类大都以 AbstractClusterInvoker
为基类,3.x 后减少了接口 ClusterInvoker
,次要包含以下几个:
Anonymous in join() in AvailableCluster
AvailableClusterInvoker
BroadcastClusterInvoker
FailbackClusterInvoker
FailfastClusterInvoker
FailoverClusterInvoker
FailsafeClusterInvoker
ForkingClusterInvoker
ZoneAwareClusterInvoker 2.7.x 新增
MergeableClusterInvoker
MockClusterInvoker 未继承 AbstractClusterInvoker
这些类失常状况下并不真正进行近程调用逻辑,他们都是将多个近程单实例调用类进行聚合加强来实现不同的集群容错逻辑,底层还是委托给 AbstractInvoker
的那些实现,负载平衡策略也是在这个层面实现的。
MockClusterInvoker
是一个比拟非凡的类,默认状况下其余的 ClusterInvoker
都会被包裹在 MockClusterInvoker
中进行加强实现服务降级和本地假装。
- 本地加强类,过滤器
这些类没有通用逻辑,他们大都是繁多的性能加强实现。
Anonymous in buildInvokerChain() in ProtocolFilterWrapper
ConsumerInvokerWrapper
DelegateInvoker
DelegateProviderMetaDataInvoker
ListenerInvokerWrapper
ProviderInvokerWrapper
Anonymous in buildInvokerChain() in ProtocolFilterWrapper
次要实现了过滤器逻辑,它将各个 Filter
转换为一个 Invoker
链表,以此实现过滤器串行可阻断的调用,起初的 dubbo 中减少了异步过滤器其实现就更加简单了些,用 CopyOfFilterChainNode
进行代替,此处不再赘述。
其余的几个加强类都比较简单,不再一一介绍,有趣味的能够翻翻源码,逻辑很简略。