前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dubbo协议解析过程

Dubbo协议解析过程

作者头像
程序员波特
发布2024-01-19 10:19:52
1710
发布2024-01-19 10:19:52
举报
文章被收录于专栏:魔法书

Dubbo协议解析过程

Dubbo有哪些底层协议

同学们以为Dubbo只有一个RPC协议吗?非也,既然是阿里巴巴出品的开源项目,那自然秉承了“包罗万象”的一贯传统。Dubbo的底层有支持多达9种通信协议,并且他们都有各自的适用场景。我们快速的一扫而过:

  1. Dubbo本尊这也是官方首推的底层通信协议
  2. RMI Java界的老法师可能会对RMI比较熟悉,没错,这个就 是JDK中“java.rmi”包下的实现,底层采用阻塞式(同步传输)的短连接+JDK中标准的二进制序列化。
    • 适用场景参数数据包大小不一,服务提供者和服务消费者的个数相近
  3. Hessian用于集成Hessian的服务,基于HTTP短连接,采用S ervlet向外暴露服务
    • 适用场景参数数据包较大,服务提供者的数量远多于消费者数量
  4. HTTP最简单的基于HTTP表单的协议
    • 适用场景可以使用浏览器直接查看,适用于需要同时给后台应用程序以及浏览器提供服务的场景(很多其他协议无法通过浏览器直接发起调用)
  5. WebService基于大名鼎鼎的Apache CXF,使用基于SOAP 的序列化技术
    • 适用场景比如公司内部的系统是由多种不同语言构成的,那么这个场景就比较适合采用WebService协议,WebService通 常使用在系统集成和跨语言调用场景
  6. REST基于标准的Java REST API (JAX-RS 2.0) 实现的RES T风格调用,Dubbo花了大力气在这部分的实现上面,它的使用风格和原生Spring MVC类似。但它不是今天的主角,同学们如果感兴趣的话可以自己花点时间去阅读REST协议的源码
  7. 杂七杂八的协议 Dubbo还支持基于Thrift, Memcached和Red is的协议,不过相信大家在职业生涯中应该是用不到的
Dubbo协议Dubbo协议的特性和性能

我们先来看一看 Dubbo协议的特性:

项目

说明

连接个数

单连接

连接方式

长连接

传输协议

TCP

底层通信框架

Netty异步NIO

序列化方式

Hessian2或Dubbo序列化

在官方的测试报告中,由于Dubbo将底层的通信框架从mina换成了Netty,大大提升了稳定性,主要体现在JVM Old区对象的数量减少了很多,因此Full GC的触发频率大幅减少。

Dubbo协议的适用场景

尺有所短寸有所长,Dubbo并不是万能药,我们在使用它之前务必要知道它的适用场景:

适用场景传入传出参数数据包较小(建议小于100K),但是并发量高的场景。简单来说就是短平快,QPS/TPS高但是数据量小的情况

不适场景尽量不要用Dubbo协议传输大数据包(比如大文件、视频、超大字符串等),这类场景建议使用上面介绍过的其他协议栈

Dubbo协议的调用流程

接下来我们通过一幅图,看一下Dubbo协议的工作流程

这次我们换个姿势,采用从中间向两边展开的方式解读这个协议工作流程

Transporter

大家注意看图片底部最中间的Transporter,这个是底层网络传输组件,目前Dubbo支持Mina和Netty。大家可能对Netty比较熟悉,但并没有接触过Mina。在Dubbo的2.0版本以后已经从Mina全面替换为Netty,基于Netty的传输层在稳定性和性能上都要更好一些。

Header & Body

接下来我们看图中的绿色部分,就是Header和Body,这部分是Dubbo定义的私有RPC协议中的数据格式部分,它是一个变长协议,由定长的Header和不定长的Body组成。

  • Header

上面是Header的结构,图片中的数字代表Header中Bit位置,下 面的文字表示这段字节所携带的信息,Header总 长度为16字节。其中Magic High=0xda, Magic Low=0xbb,标识了这是个Dubbo协议。

后面紧跟着16-23比特位带有两个信息:当前请求的类型以及序列化的方式。其中高四位表示当前请求的Request flag (有 三种类型: REQUEST, TWOWAY和EVENT),低四位表示序列化的方式,Du bbo有四种序列化方式,分别对应Dubbo, FastJson, Hessian2和Java 原生序列化。

接下来24-31位是响应报文才有的信息,作为Request报文并不包含这部分信息。其中定义了详情请求的状态,比如OK,BAD_ RESP ONSE,SERVER TIMEOUT。注意这些Status Code可不是HTTP St atus,而是Dubbo自定义的状态。

最后两个部分分别对应Request ID (唯一请求ID)和经过序列化后的Body内容的长度。

  • Body

这部分是Dubbo协议中不定长的部分,在传输之前会经过序列化处理,对于一个请求包来说,主要包含三部分的信息:

  1. 协议版本Dubbo当前的版本
  2. 寻址信息目标服务的名称,服务版本,方法名,方法签名类型
  3. 数据方法参数值,附件形式的数据等
Client, Server和ThreadPool

Client对应调用发起方,Server对 应服务提供方。

  • Client在发起调用之前会将整个消息进行序列化,组装成上面的Header+ Body的变长协议格式
  • Server根据Header里标识的序列化方式,对Body 中的内容进行反序列化
  • ThreadPool响应服务调用请求的线程池,可以选择配置Fix ed或Cached Thread Pool
Dispatcher线程派发模型

Dispatcher用来创建具有线程派发能力的ChannelHandler,将来访Request派发到线程池或当前I0线程。我们可以给Dispatcher配置5种派发策略

策略

说明

all

所有消息都派发到线程池,包括请求,响应,连接事件,断开事件等

direct

所有消息都不派发到线程池,全部在IO线程上直接执行

message

只有请求和响应消息派发到线程池,其它消息均在IO线程上执行

execution

只有请求消息派发到线程池,不含响应。其它消息均在IO线程上执行

connection

在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池

协议的约束

既然Dubbo协议应用了序列化和反序列化技术,那么对我们数据传输有几个约束条件:

  1. Serializable 参数和返回值必须实现Serializablc接口,否则在调用的时候会抛出无法序列化反序列化的异常
  2. 使用JDK原生类 比如Map、Date、 List、 Number等-系列接 口,我们不能在返回值和参数中使用自己创建的实现类,只能使用JDK原生的接口实现类。
服务的同步和异步调用

Dubbo支持同步和异步两种调用方式,整个链路流程非常复杂,我们只抓重点看下两个调用模式的不同

  • 异步调用 异步调用还可细分为“有返回值”的异步调用和“无返回值”的异步调用。所谓“无返回值”异步调用是指服务消费方只管调用,但不关心调用结果,此时Dubbo会直接返回一个空的RpcResult。若要使用异步特性,需要服务消费方手动进行配置。
  • 同步调用 这是默认情况下Dubbo所采用的调用方式,调用方等待服务提供者返回处理结果

本文已收录至我的个人网站:程序员波特,主要记录Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源,让想要学习的你,不再迷茫。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Dubbo协议解析过程
    • Dubbo有哪些底层协议
      • Dubbo协议Dubbo协议的特性和性能
        • Dubbo协议的适用场景
          • Dubbo协议的调用流程
            • Transporter
            • Header & Body
          • Client, Server和ThreadPool
            • Dispatcher线程派发模型
              • 协议的约束
                • 服务的同步和异步调用
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档