美文网首页
dubbo学习笔记

dubbo学习笔记

作者: 7d972d5e05e8 | 来源:发表于2020-05-21 23:59 被阅读0次

一、消费者启动--到底干了些啥

  1. 消费者启动过程,其实只是给消费者初始化invokers。纯粹只是把消费者所关心服务的提供者列表,给初始化好。连分组信息其实也是消费者在本地去匹配的,因为消费者会把服务所有的提供者全部初始化成invoker列表。
  2. 在消费者初始化invoker的时候,会提前建立到提供者ip的connection。这里为啥这么早就创建连接呢,假如连接建立了,这个服务其实业务根本就没去调用过,岂不是浪费。dubbo为啥不用懒加载呢?

我猜测:1. 如果是懒加载,那么在服务调用的时候有可能连接建立不上,这个时候影响可能比较大,违背尽量让错误提前暴露的原则。2. 提前建立连接,其实并不浪费。tcp连接毕竟不像mysql数据连接池的连接那么宝贵,提供者就算多一个tcp连接在那维持着,用了netty这种NIO,其实是消耗不了多少资源的。3. 提前建立连接,不至于让第一次调用很慢,期望到达所有请求都很稳定。

  1. 提供者的invokers列表有了,具体调用哪个invoker是由服务调用正在发起的时候确定。启动时,消费者只要提供服务列表出来,其他就不管了。
  2. dubbo的服务治理提供了集群模块的抽象,作为中间层 消费者调用 -> 集群Invoker -> real provider Invoker,屏蔽服务治理的细节。比如:服务路由,调用失败恢复等等服务治理相关的功能。

服务治理好像除了服务路由和失败恢复,也没其他的功能了。

二、dubbo调用编码

编码方法:com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec#encodeRequest

protected void encodeRequest(Channel channel, ChannelBuffer buffer, Request req) throws IOException {
        Serialization serialization = getSerialization(channel);
        // header.
        byte[] header = new byte[HEADER_LENGTH];
        // set magic number.
        Bytes.short2bytes(MAGIC, header);

        // set request and serialization flag.
        header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());

        if (req.isTwoWay()) header[2] |= FLAG_TWOWAY;
        if (req.isEvent()) header[2] |= FLAG_EVENT;

        // set request id.
        Bytes.long2bytes(req.getId(), header, 4);

        // encode request data.
        //先获取现在的buffer能够写数据的起始位置
        int savedWriteIndex = buffer.writerIndex();
        //重新当前buffer的起始位置,新位置=上面的位置 + 16字节。目的是为了先写body
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);
        //把buffer流赋给bos。因为:buffer只接受二进制,而data是文本。需要序列化器进行序列化
        ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
        ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
        if (req.isEvent()) {
            encodeEventData(channel, out, req.getData());
        } else {
            encodeRequestData(channel, out, req.getData());
        }
        out.flushBuffer();
        bos.flush();
        bos.close();
        //序列化器把所有data一次性全部写入到buffer中,然后得到写入的长度
        int len = bos.writtenBytes();
        checkPayload(channel, len);
        //把长度写入到header数组中
        Bytes.int2bytes(len, header, 12);

        //buffer先写入数据,后写入header。这里把buffer的起始位置设置回去。起始位置还是刚开始的位置。这里很关键
        buffer.writerIndex(savedWriteIndex);
        //真正的把16字节的header写入到buffer正确位置上。
        buffer.writeBytes(header); // write header.
        //设置buffer真正的,可以接受新数据的起始位置。为下个请求用,因为buffer是通用的,只有写满后才会flush出去。
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    }

三、AbstractInvoker 和 AbstractProxyInvoker的区别

AbstractInvoker全路径:com.alibaba.dubbo.rpc.protocol.AbstractInvoker
AbstractProxyInvoker全路径:com.alibaba.dubbo.rpc.proxy.AbstractProxyInvoker

AbstractInvoker是消费者Invoker的调用方法。AbstractProxyInvoker是提供者调用接口的实现。两个都是表示invoker实体,但是两个的作用完全不一样。每次遇到invoker.invoke()方法的时候,用idea看接口实现总是搞错。这两个方法类和方法都太像了。。。

相关文章

  • Dubbo 服务调用 总结(八)

    笔记简述结合之前学习的两篇笔记 Dubbo 服务调用 源码学习(上)(六)和 Dubbo 服务调用 源码学习(下)...

  • Dubbo 服务暴露 总结(五)

    笔记简述Dubbo服务暴露之前分为了两小节Dubbo 服务暴露 源码学习(上)(三) 和Dubbo 服务暴露 源码...

  • Dubbo 2.7.7 学习笔记 1

    Dubbo 2.7.7 起步入门学习笔记 本文档基于 Dubbo 中文官方文档编写,详情请参见 Dubbo 中文官...

  • Dubbo | Dubbo快速上手笔记 - 环境与配置

    前言 比较基础的dubbo学习笔记,一些参考资料如下: 尚硅谷Dubbo教程(dubbo经典之作)[https:/...

  • Dubbo 简要介绍和使用 学习(一)

    笔记简述本学习笔记主要是介绍了dubbo的基础内容,简单说明了dubbo、rpc、soa、zk等概念,并没有直接贴...

  • Dubbo SPI 源码学习 & admin安装(二)

    笔记简述本学习笔记主要是介绍了SPI的使用以及原理,dubbo是如何实现自身的SPI,dubbo如何使用的可以看D...

  • Dubbo学习笔记

    Dubbo简介 Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可...

  • Dubbo学习笔记

    1. Dubbo入门 Dubbo是一款高性能Java RPC框架,常用来构建分布式系统。Dubbo为开发者提供了三...

  • Dubbo学习笔记

    0 写在前面 项目使用Dubbo近一年了,期间大大小小遇到过一些问题。在这个过程中也一直在尝试阅读Dubbo源码,...

  • Dubbo学习笔记

    [TOC] 一、分布式基本知识 1.1) 架构演变 先给出dubbo官方的图,图片表示了架构的演变。然后我说一下自...

网友评论

      本文标题:dubbo学习笔记

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