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

Dubbo客户端发送逻辑查询

时间:2023-04-02 10:41:15 Java

最近在看dubbo的源码,记录一些阅读要点。本文主要探讨dubbo客户端请求发送的逻辑;接口声明和客户端调用方法如下:META-INF/spring/dubbo-demo-consumer.xml"});context.start();DemoServicedemoService=(DemoService)context.getBean("demoService");//获取远程服务代理Stringhello=demoService.sayHello("world");//调用远程方法System.out.println(hello);//获取结果}}以Dubbo官方demo为例客户端调用栈:22.writeAndFlush:244,AbstractChannel(io.netty.channel)21.send:116,NettyChannel(com.alibaba.dubbo.remoting.transport.netty4)20.发送:336,AbstractClient(com.alibaba.dubbo.remoting.transport)19.send:58,AbstractPeer(com.alibaba.dubbo.remoting.transport)18.请求:146,HeaderExchangeChannel(com.alibaba.dubbo.remoting.exchange.support.header)17。request:115,HeaderExchangeClient(com.alibaba.dubbo.remoting.exchange.support.header)16.request:95,ReferenceCountExchangeClient(com.alibaba.dubbo.rpc.protocol.dubbo)15。doInvoke:126,DubboInvoker(com.alibaba.dubbo.rpc.protocol.dubbo)14。invoke:185,AbstractInvoker(com.alibaba.dubbo.rpc.protocol)13.invoke:86,ListenerInvokerWrapper(com.alibaba.dubbo.rpc.listener)12.invoke:75,MonitorFilter(com.alibaba.dubbo.monitor.support)11.invoke:93,ProtocolFilterWrapper$1(com.alibaba.dubbo.rpc.protocol)10。invoke:55,FutureFilter(com.alibaba.dubbo.rpc.protocol.dubbo.filter)9.invoke:93,ProtocolFilterWrapper$1(com.alibaba.dubbo.rpc.protocol)8.invoke:53,ConsumerContextFilter(com.alibaba.dubbo.rpc.filter)7.invoke:93,ProtocolFilterWrapper$1(com.alibaba.dubbo.rpc.protocol)6.invoke:59,InvokerWrapper(com.alibaba.dubbo.rpc.protocol)5.doInvoke:90,FailoverClusterInvoker(com.alibaba.dubbo.rpc.cluster.su端口)4。invoke:294,AbstractClusterInvoker(com.alibaba.dubbo.rpc.cluster.support)3.invoke:84,MockClusterInvoker(com.alibaba.dubbo.rpc.cluster.support.wrapper)2.invoke:57,InvokerInvocationHandler(com.alibaba.dubbo.rpc.proxy)1.sayHello:-1,proxy0(com.alibaba.dubbo.common.bytecode)main:38,Consumer2(com.alibaba.dubbo.demo.consumer)dubbo虽然现在经历了比较大的版本变化,但是其核心调用逻辑还没有改了,我们在传输层组件netty的writeAndFlush方法下打断点得到上面的调用栈,然后一步步拆解:1.proxy0是dubbo使用ProxyFactory代理类生成的,默认是javassist生成的字节码,具体的生成代码逻辑在com.alibaba.dubbo.common.bytecode.Proxy.getProxy(Class...)2,InvokerInvocationHandler代理类的具体处理逻辑,经过代理可以得到方法签名调用接口的方法和参数,可以参考jdk自带的动态代理了解。3、MockClusterInvoker是由MockClusterWrapper创建的clusterInvoker,MockClusterWrapper是一个集群的自动包装(Wrapper)类。dubbo的spi扩展在初始化的时候会自动搜索Wrapper并打包到扩展实现上。参考dubbo的SPI扩展。MockClusterInvoker提供了降级服务和本地伪装的能力。结合MockInvokersSelector实现服务降级,结合MockProtocol和MockInvoker实现本地伪装4-5,FailoverClusterInvoker是默认的集群容错策略,即故障自动切换值得一提的是,负载均衡器(LoadBalance)也在该组件下工作。6、InvokerWrapper是Invoker的增强类,绑定URL信息,实现Node接口。从构造函数的角度来看,它不是一个SPIWrapper类。它由RegistryDirectory手动实例化。数组和Invoker实现组成一个过滤器列表;同样ProtocolFilterWrapper也是一个Wrapper包装类,通过SPI自动包装在默认的Protocol实现类DubboProtocol上,类似3。13.ListenerInvokerWrapper是Invoker的装饰器模式增强,实现了invoker的refer和destroy的监听回调,但是ListenerInvokerWrapper并不是一个SPI包装器(Wrapper),因为它没有Wrapper类的标志性构造函数14-15,它是DubboInvoker(默认的dubbo协议Invoker)的调用(invoke)逻辑,这个方法会调用ExchangeClient向网络发送请求。ExchangeClient包括初始化逻辑,例如编码器和序列化组件。最后将这些组件设置到netty的channelhandler中。当调用nettychannel的write方法时,会执行特定的编码和顺序。16、ReferenceCountExchangeClient在ExchangeClient的基础上增加了引用计数,在ExchangeClient实现共享时提供引用计数,可以为关闭ExchangeClient时的决策提供依据;17-18。HeaderExchangeClient是Client的装饰器模式增强类,增加了Heartbeat逻辑;19-20,是NettyClient的发送逻辑,委托父类实现21,是NettyClient发送逻辑最终委托给NettyChannel来实现22最后委托给netty的channel.writeAndFlush来实现网络数据的发送。这个过程中执行了编码和序列化,涉及到netty的使用,不过我会解释太多