最近在浏览dubbo的源码,记录下浏览的一些关键点,本文次要探索dubbo客户端申请发送逻辑;
接口申明及客户端调用形式如下:
public interface DemoService { String sayHello(String name);}public class Consumer { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"}); context.start(); DemoService demoService = (DemoService) context.getBean("demoService"); // get remote service proxy String hello = demoService.sayHello("world"); // call remote method System.out.println(hello); // get result }}
以dubbo官网demo为例的客户端调用栈:
22. writeAndFlush:244, AbstractChannel (io.netty.channel)21. send:116, NettyChannel (com.alibaba.dubbo.remoting.transport.netty4)20. send:336, AbstractClient (com.alibaba.dubbo.remoting.transport)19. send:58, AbstractPeer (com.alibaba.dubbo.remoting.transport)18. request: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.support)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 代理类的具体解决逻辑,通过代理能够拿到调用接口的办法签名Method及参数,能够参考jdk自带的动静代理来了解
3、MockClusterInvoker是 MockClusterWrapper 创立的 clusterInvoker,而 MockClusterWrapper 是 一个cluster的主动包装(Wrapper)类,dubbo的 spi扩大在初始化的时候会主动寻找 Wrapper 包装在扩大实现上,参考dubbo的 SPI 扩大, MockClusterInvoker 提供了 服务降级和本地假装的能力, 联合 MockInvokersSelector 实现服务降级,联合 MockProtocol、MockInvoker 实现本地假装
4-5、FailoverClusterInvoker 是默认的集群容错策略,即失败主动切换策略,值得一提的是 负载均衡器(LoadBalance)也是工作在这个组件下
6、InvokerWrapper 是 Invoker 的加强类,绑定了 URL 信息, 实现了 Node 接口,实在实现还是委托给外部的 Invoker 实例,从结构器上看它并不是一个 SPI Wrapper 类,它是被 RegistryDirectory 手动实例化的
7-12、 ProtocolFilterWrapper$1 是 过滤器(Filter) 链,ProtocolFilterWrapper 是对 Protocol的加强,退出了过滤器性能,他将 filter 数组与 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,在调用 netty channel的write 办法时会执行具体的编码和序列化
16、ReferenceCountExchangeClient 在 ExchangeClient 的根底上减少了援用计数,在 ExchangeClient 实现共享时提供援用计数,能够为决策敞开 ExchangeClient 时提供根据;
17-18、HeaderExchangeClient 是 Client 的一个装璜者模式加强类,为 Client 减少了心跳逻辑;
19-20、 是 NettyClient 的发送逻辑,委托父类的实现
21、是 NettyClient 的发送逻辑最终委托给 NettyChannel 来实现
22、最终委托给 netty 的 channel.writeAndFlush 实现网络数据的收回,编码和序列化就是在这个过程中执行的,这个就牵涉到netty的应用了不过多解释