美文网首页dubbo源码
dubbo client发送逻辑探究

dubbo client发送逻辑探究

作者: Foghost | 来源:发表于2022-12-28 12:09 被阅读0次

    最近在阅读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的使用了不过多解释

    相关文章

      网友评论

        本文标题:dubbo client发送逻辑探究

        本文链接:https://www.haomeiwen.com/subject/ewaoqdtx.html