本文聊聊 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 进行代替,此处不再赘述。

其余的几个加强类都比较简单,不再一一介绍,有趣味的能够翻翻源码,逻辑很简略。