当前位置: 首页 > 后端技术 > Java

dubboinvoker分析

时间:2023-04-01 14:26:10 Java

本文讲的是dubbo的核心模型Invoker,在dubbo官网是这样描述的:Invoker是一个实体域,是Dubbo的核心模型,其他模型都接近,或者转化为它,代表一个可执行体,可以向其发起invoke调用,它可以是本地实现,也可以是远程实现,也可以是集群实现。调用者是执行者的抽象。执行者可以是本地也可以是远程,可以是集群也可以是单实例,可以是真实的业务实现也可以是伪装的本地实现,可以是dubbo协议也可以是其他协议。它的抽象层次很高,不关心具体的实现,只关心输入输出。首先看Invoker的接口声明:publicinterfaceInvokerextendsNode{//这个Invoker可执行文件就是携带的接口,比如DemoServiceClassgetInterface();//核心调用模型,传入一个Invocation会话域,返回一个带结果的实体Resultinvoke(Invocationinvocation)throwsRpcException;}另一个核心模型Protocol,负责管理Invoker的生命周期,其API无处不在调用者,查看其接口声明:publicinterfaceProtocol{//服务器暴露端口intgetDefaultPort();//服务器公开方法Exporterexport(Invokerinvoker)throwsRpcException;//客户端引用的方法Invokerrefer(Classtype,URLurl)throwsRpcException;//Destroy方法,服务端和客户端都使用voiddestroy();}Invoker是dubbo的灵魂,服务端和客户端都围绕这个Entities进行操作,不同的Invoker携带不同的调用方法。从它们的使用场景来看,可以分为以下几类:服务端代理类,其实现类主要使用AbstractProxyInvoker作为父类,主要包括:JavassistProxyFactory中getInvoker()中的AnonymousJdkProxyFactory中getInvoker()中的AnonymousByteBuddyProxyInvoker//3.x添加它们的主要作用是将远程调用与本地具体执行的业务方法关联到服务器端,也就是本地业务接口的代理,这也是为什么取名为proxyInvoker的原因,因为框架本身无法提前知道业务接口。这里通过字节码编译技术和Wrapper对业务接口进行封装,最后通过Wrapper#invokeMethod调用真正的实现。这里以源码demo中的DemoService实现类为例,看看生成的invokeMethod实现:var4)抛出InvocationTargetException{DemoServicevar5;try{var5=(DemoService)var1;}catch(Throwablevar8){thrownewIllegalArgumentException(var8);}try{//根据接口和方法名找到对应的业务实现并真正调用if("sayHello".equals(var2)&&var3.length==1){returnvar5.sayHello((String)var4[0]);}}catch(Throwablevar9){thrownewInvocationTargetException(var9);}thrownewNoSuchMethodException("在com.alibaba.dubbo.demo.DemoService类中找不到方法\""+var2+"\"。");}}服务器端生成Wrapper类后,框架层不会直接调用业务实现类,而是通过Wrapper类委托给真正的实现类,从而实现与业务的解耦。这些类大多使用AbstractInvoker作为基类,主要包括:MemcachedProtocol中refer()中的AnonymousRedisProtocol中refer()中的AnonymousDubboInvokerInjvmInvokerThriftInvokerGrpcInvoker2.7.x新增TripleInvoker3.x新增MockInvoker大部分远程调用实现不继承AbstractInvoker的是具体协议的实现,即Protocol#refer中的对象,只针对单个服务器实例,然后在集群模式下使用集群ClusterInvoker来增强。它的内部实现大部分是通过socket链接编码本地调用remote,比如DubboInvoker,还有一些特殊的比如InjvmInvoker,直接在jvm本地调用,不使用sockets。MockInvoker是一个特殊的实现。它不与特定协议捆绑在一起。主要用于实现本地伪装,主要用于MockClusterInvoker和服务降级。集群远程调用类这些类大都以AbstractClusterInvoker为基类,3.x后增加了接口ClusterInvoker,主要包括以下几个:Anonymousinjoin()inAvailableClusterAvailableClusterInvokerBroadcastClusterInvokerFailbackClusterInvokerFailfastClusterInvokerFailoverClusterInvokerFailsafeClusterInvokerForkingClusterInvokerZoneAwareClusterInvoker2.7.x新增MergeableClusterInvokerMockClusterInvoker不继承AbstractClusterInvoker的类在正常情况下实际上不执行远程调用逻辑。它们聚合并增强了多个远程单实例调用类,实现了不同的集群容错逻辑。底层还是委托给AbstractInvoker的那些实现,负载均衡策略也是在这一层实现的。MockClusterInvoker是一个特殊的类。默认情况下,其他ClusterInvoker会被包裹在MockClusterInvoker中,以增强服务降级和局部伪装。局部增强类、过滤器类没有共同的逻辑,大多是单一的功能增强实现。ProtocolFilterWrapper中的buildInvokerChain()中的AnonymousConsumerInvokerWrapperDelegateInvokerDelegateProviderMetaDataInvokerListenerInvokerWrapperProviderInvokerWrapper中的AnonymousProtocolFilterWrapper中的buildInvokerChain()中的Anonymous主要实现filter逻辑,它将每个Filter调用串行链转换为Invoker在dubbo中加入异步filter使得实现更加复杂。使用CopyOfFilterChainNode代替,这里不再赘述。其他几个增强类比较简单,就不一一介绍了。有兴趣的可以翻翻源码。逻辑很简单。

最新推荐
猜你喜欢