Dubbo学习笔记之零 协议

作者: 周小WA | 来源:发表于2018-05-29 00:20 被阅读15次

    前言

    该模块封装了RPC调用,使服务consumer透明使用,以Invocation,Result为中心,扩展接口为 Protocol, Invoker, Exporter,Protocol封装了使用Proxy来初始化Invoker,然后再增加一些Filter实现相关监控。Exporter封装了服务暴露以及数据传输。主要接口/类包括Protocol,Exporter,ProxyFactory,Invoker,Result,Filter,RpcContext。

    核心类分析

    下面就分析下几个主要接口/类的代码逻辑。

    Protocol

    <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
    <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
    void destroy();
    int getDefaultPort();
    

    export方法

    • 暴露服务接口,用于服务消费者调用。
    • 该接口必须是幂等的,一次调用和多次调用结果是一致的。
    • invoker参数是由框架传入,protocol本身并不关心该对象。

    refer方法

    • 用于服务消费端调用,生成invoker,然后通过proxy生成远程调用对象
    • 参数url用来 标识服务提供者调用相关信息(ip/port/)

    Invoker

    用于RPC中接口透明调用,实现了服务消费者接口请求逻辑,以及服务提供者接口处理逻辑

    Exporter

    用于返回服务Invoker对象,以及当前所有暴露接口的访问信息,以DubboExporter为例

        private final String key;
        private final Map<String, Exporter<?>> exporterMap;
        public DubboExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
            super(invoker);
            this.key = key;
            this.exporterMap = exporterMap;
        }
    

    代码中的key就是暴露接口的访问信息。

    服务发布流程

    1. 调用export接口(传入invoker对象,具体生成逻辑在服务代理中细说)
    2. 生成exporter实例;
    3. 生成信息交换层Exchanger(数据的发送与接收)
    4. 使用网络传输层绑定host/port(Transport)
    5. 使用Netty/Mina/Grizzly封装底层数据通信逻辑。

    具体使用代码

    protocol.export(proxy.getInvoker(echoService, EchoService.class,
                URL.valueOf("dubbo://127.0.0.1:9020/" + EchoService.class.getName() + "?codec=exchange")));
    

    服务引用流程

    逻辑和服务暴露类似,传入需要消费的服务以及联系信息,由具体协议实现返回服务提供者的Invoker对象即可。中间通过Exchanger调用Transport 生成Client,从而进行与服务提供者数据通信。

     echoService = proxy.getProxy(protocol.refer(EchoService.class,
                URL.valueOf("dubbo://127.0.0.1:9020/" + EchoService.class.getName() + "?codec=exchange")));
            echoService.sayHello("Hello World");
    

    Protocol类型

    dubbo

    Dubbo 缺省协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。
    反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。


    image.png
    • Transporter: mina, netty, grizzy
    • Serialization: dubbo, hessian2, java, json
    • Dispatcher: all, direct, message, execution, connection
    • ThreadPool: fixed, cached

    特性

    缺省协议,使用基于 mina 1.1.7 和 hessian 3.2.1 的 tbremoting 交互。

    • 连接个数:单连接
    • 连接方式:长连接
    • 传输协议:TCP
    • 传输方式:NIO 异步传输
    • 序列化:Hessian 二进制序列化
    • 适用范围:传入传出参数数据包较小(建议小于100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串。
    • 适用场景:常规远程服务方法调用

    协议配置

    <dubbo:protocol name="dubbo" port="20880" />
    

    rmi

    RMI 协议采用 JDK 标准的 java.rmi.* 实现,采用阻塞式短连接和 JDK 标准序列化方式。

    hession

    Hessian协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。
    Dubbo 的 Hessian 协议可以和原生 Hessian 服务互操作,即:

    • 提供者用 Dubbo 的 Hessian 协议暴露服务,消费者直接用标准 Hessian 接口调用
    • 或者提供方用标准 Hessian 暴露服务,消费方用 Dubbo 的 Hessian 协议调用。

    特性

    • 连接个数:多连接
    • 连接方式:短连接
    • 传输协议:HTTP
    • 传输方式:同步传输
    • 序列化:Hessian二进制序列化
    • 适用范围:传入传出参数数据包较大,提供者比消费者个数多,提供者压力较大,可传文件。
    • 适用场景:页面传输,文件传输,或与原生hessian服务互操作

    协议配置

    <dubbo:protocol name="hessian" port="8080" server="jetty" />
    

    http

    基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现

    特性

    • 连接个数:多连接
    • 连接方式:短连接
    • 传输协议:HTTP
    • 传输方式:同步传输
    • 序列化:表单序列化
    • 适用范围:传入传出参数数据包大小混合,提供者比消费者个数多,可用浏览器查看,可用表单或URL传入参数,暂不支持传文件。
    • 适用场景:需同时给应用程序和浏览器 JS 使用的服务。
      协议配置
    <dubbo:protocol name="http" port="8080" />
    

    redis

    基于 Redis 实现的 RPC 协议 ,提供客户端访问redis服务。

    协议配置

    <dubbo:reference id="store" interface="java.util.Map" group="member" />
    

    除了上述几种,还有thrift,webservice,memcached,可以去官方文档细看。

    参考

    dubbo官方用户手册

    相关文章

      网友评论

        本文标题:Dubbo学习笔记之零 协议

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