Dubbo远程传输协议详解

2023-11-20

前言

上次小编为大家带来了Dubbo调用及容错机制详解,不知道大家有没有去看小编最后留下的问题,欢迎对文章进行评论也希望大家和小编多多交流。今天接着为大家带来Dubbo的内容,传输协议,上次调用机制中并没有涉及Dubbo传输的协议,这次容小编娓娓道来。

Dubbo核心协议

RPC协议概念

这边涉及到小编曾经被问到的问题,问dubbo采用什么协议,一般问这个问题的话,主要是针对应用协议而不是网络传输协议,所以TCP/UDP显然是不符合的,应用协议是在网络传输的基础至少构建出来的。大家要分清两种协议。以及知道面试官问的问题。
在⼀个典型RPC的使⽤场景中,包含了服务发现、负载、容错、网络传输、序列化等组件,其中RPC协议就指明了程序如何进行网络传输和序列化。也就是说⼀个RPC协议的实现就等于⼀个非透明的远程调用实现,那他是如何做到的的呢?如下图:
在这里插入图片描述
RPC协议组成:

1.地址:服务提供者地址和端口
2.报文编码:协议报⽂编码,分为请求头和请求体两部分。
3.序列化方式:将请求体序列化成对象

  • a.Hessian2Serialization
  • b.DubboSerialization
  • c.JavaSerializationd.JsonSerialization

4.运行服务:网络传输实现

  • a.netty
  • b.mina
  • c.RMI服务
  • d.servlet容器(jetty、Tomcat、Jboss)

dubbo支持协议

名称 实现描述 连接描述 适用场景
dubbo 传输服务:mina,netty(默认),grizzy;序列化:hessian2(默认),java,fastjson;报文:自定义报文 单个⻓连接NIO异步传输 1、常规RPC调用 2、传输数据量小 3、提供者少于消费者
rmi 传输:javarmi服务; 序列化:java原⽣⼆进制序列化 多个短连接.BIO同步传输 1、常规RPC调用 2、与原RMI客户端集成 3、可传少量⽂件 4、不防⽕墙穿透
hessian 传输服务:servlet容器; 序列化:hessian⼆进制序列化 基于Http协议传输,依赖servlet容器配置 1、提供者多于消费者 2、可传⼤字段和⽂件
http 传输服务:servlet容器; 序列化:java原⽣⼆进制序列化 依赖servlet容器配置 1、数据包⼤⼩混合
thrift 与thriftRPC实现集成,并在其基础上修改了报⽂头 ⻓连接、NIO异步传输

关于RMI不⽀持防⽕墙穿透的补充说明:
原因在于RMI底层实现中会有两个端口,⼀个是固定的用于服务发现的注册端口,另外会⽣成⼀个随机端⼝⽤于网络传输。因为这个随机端口就不能在防⽕墙中提前设置开放开。所以存在防⽕墙穿透问题。

dubbo协议(重点)

Dubbo协议是专门RPC远程调用所设计的协议,也是Dubbo默认协议,它是⼀种⼆进协议,特性是:体积小,编解码速度快。
协议报文
在这里插入图片描述

  • magic:类似java字节码文件里的魔数,用来判断是不是dubbo协议的数据包。魔数是常量0xdabb,⽤于判断报⽂的开始。
  • flag:标志位,⼀共8个地址位。低四位用来表示消息体数据⽤的序列化⼯具的类型(默认hessian),高四位中,第⼀位为1表示是request请求,第⼆位为1表示双向传输(即有返回response),第三位为1表示是心跳ping事件。
  • status:状态位,设置请求响应状态,dubbo定义了⼀些响应的类型。具体类型见com.alibaba.dubbo.remoting.exchange.Response
  • invokeid:消息id,long类型。每⼀个请求的唯⼀识别id(由于采⽤异步通讯的方式,⽤来把请求request和返回的response对应上)
  • bodylength:消息体Body长度,Int类型,即记录BodyContent有多少个字节。
    运行服务
    每个协议的使用都必须有⼀个运行服务器,用于进行IO数据传输,和编解码操作。比如Http协议的运⾏服务就是Tomcat\Jetty\Jboss\Apache\Nginx等。由于Http是知名的公共协议支持的服务器较多,如果是私有应用协议,或者Dubbo这类的特殊协议,就必须得自己使用Socket开发服务器,费时费力。还有另外⼀个选择就是选择netty、minia等网络框架进行开发,可节约⼤量开发成本。Dubbo同时⽀持Netty和minia,我们就用默认的Netty即可。
#服务选择netty,mina
dubbo.protocol.server=netty

线程池
Dubbo所依懒的Netty它是非阻塞式的IO通信,其网络传输所需线程并不多。但在业务处时,由于每个业务的响应时间不确定就需要⼀定数量的线程来支撑。以下是关于线程相关配置

#线程池类型fixed,cached,limited,eager
dubbo.protocol.threadpool=limited
#核心线程数,如果不够就加到队列 在CachedThreadPool,EagerThreadPool,LimitedThreadPool中使用
dubbo.protocol.corethreads=10
#核心线程满进入等待队列,如果满了创建新线程
dubbo.protocol.queues=10
#最大线程数量,默认200,超出后抛异常
dubbo.protocol.threads=100
dubbo.protocol.iothreads = 100
  • threadpool: 线程池类型,可选:fixed,cached,limited,eager, ⼀般配置cached
  • threads:服务最⼤线程池,根据上⾯的计算,来适当配置
  • iothreads:cpu个数+1 io线程池大小(固定大小),无需优化
  • accepts:服务提供方最大可接受连接数(长连接),默认0

相关源码
org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool//固定线程数量 (默认)org.apache.dubbo.common.threadpool.support.limited.LimitedThreadPool//增涨线程池org.apache.dubbo.common.threadpool.support.cached.CachedThreadPool//可回收线程,默认保持1分钟org.apache.dubbo.common.threadpool.support.eager.EagerThreadPool//自定义线程,先增涨后⼊队列,默认保持1分钟
大家可以看下源码。这边就不贴出代码了。这基本就是java并发的内容了,如果时间小编也会为大家带来并发编程的内容。

序列化
客户端与服务端在传递参数和结果时,都是JAVA对象,为了把这些对象能在⽹络上进⾏传输,必须把这些对象进行⼆进制序列化。好的序列化框架应⽀持以下特性:
1.体积小
2.序列化速度快
3.容错性强
第1、2点目的就是为了提⾼性能,而第3点目的是为版本升级时,最大化保证兼容(当然如果支持跨语言就更好了)。目前这几方面做得比较好的组件是Hessian2,这也是Dubbo协议默认序列化框架。
Hessian2序列化

  • 参数及返回值需实现 Serializable接口
  • 参数及返回值不能自定义实现 List,Map,Number,Date,Calendar等接口,只能用JDK自带的实现,因为 hessian会做特殊处理,自定义实现类中的属性值都会丢失。
  • Hessian序列化,只传成员属性值和值的类型,不传方法或静态变量,兼容情况
数据通讯 情况 结果
A ->B 类A多⼀种 属性(或者说类B少⼀种 属性) 不抛异常,A多的那 个属性的值,B没有, 其他正常
A ->B 枚举A多⼀种 枚举(或者说B少⼀种 枚举),A使⽤多 出来的枚举进⾏传输 抛异常
A ->B 枚举A多⼀种 枚举(或者说B少⼀种 枚举),A不使⽤ 多出来的枚举进⾏传输 不抛异常,B正常接 收数据
A ->B A和B的属性 名相同,但类型不相同 类型之间可以转换的不报错,如A类Long id,B类是String id,否则报异常
A ->B serialId不相同 正常传输

当接口增加方法,对客户端⽆影响,如果该方法不是客户端需要的,客户端不需要重新部署。输⼊参数和结果集中增加属性,对客户端⽆影响,如果客户端并不需要新属性,不用重新部署。输⼊参数和结果集属性名变化,对客户端序列化⽆影响,但是如果客户端不重新部署,不管输入还是输出,属性名变化的属性值是获取不到的。总结:服务器端和客户端对领域对象并不需要完全⼀致,而是按照最⼤匹配原则。

其他框架的序列化
此外Dubbo协议还⽀持以下序列化组件:

序列化框架 特点
fastjson ⽂本型:体积较⼤,性能慢、跨语⾔、可读性⾼
fst ⼆进制型:体积⼩、兼容JDK原⽣的序列化。要求JDK1.7⽀持。
java ⼆进制型:在JAVA原⽣的基础上可以写⼊Null
compactedjava ⼆进制型:与java类似,内容做了压缩
nativejava ⼆进制型:原⽣的JAVA序列化
kryo ⼆进制型:体积⽐hessian2还要⼩,但容错性没有hessian2好

在这里插入图片描述

序列化配置

#序列化框架
dubbo.protocol.serialization=fastjson  

RMI协议

RMI协议是原生的JAVA远程调⽤协议,其特性如下:

  • 运行服务:JAVA基于Socket自身实现
  • 连接方式:短连接,BIO同步传输
  • 序列化:JAVA原生,不支持其它序列化框架
  • 调⽤场景:与原RMI客户端集成
  • 其它特性:防火墙穿透问题
#mac查找当前进程所占端口
lsof-nP-p42161|grepLISTEN

Http协议

基于 HTTP表单的远程调⽤协议,采⽤ Spring的 HttpInvoker实现。其特性如下:

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

Hessian协议

Hessian协议用于集成 Hessian的服务,Hessian底层采用 Http通讯,采⽤Servlet暴露服务,Dubbo缺省内嵌 Jetty作为服务器实现。Dubbo的 Hessian协议可以和原生 Hessian服务互操作,即:提供者用 Dubbo的 Hessian协议暴露服务,消费者直接用标准 Hessian接口调用或者提供方用标准 Hessian暴露服务,消费方用 Dubbo的 Hessian协议调用。其特性如下:

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

总结

上面大家只要重点了解dubbo协议即可,如果想了解更多内容可以去dubbo官网>协议参考手册。在Dubbo中⼀个服务可以同时暴露给多个协议,这就是多协议使用,但一般情况下没有那么做的。好了今天就讲到这儿。谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dubbo远程传输协议详解 的相关文章

随机推荐

  • Cannot read property bindings of null 解决方法

    安装 babel preset env yarn add babel preset env 或 npm install babel preset env webpack config js presets env 替换成 presets b
  • rabbitmq基础2——rabbitmq二进制安装和docker安装、基础命令

    文章目录 一 RabbitMQ安装 1 1 二进制安装 1 2 rabbitmqctl工具 1 3 docker安装 二 rabbitmq基础命令 2 1 多租户与权限类 2 1 1 创建虚拟主机 2 1 2 查看虚拟主机信息 2 1 3
  • 泛微最新漏洞汇总

    泛微OA e cology前台接口SQL注入漏洞 POST mobile browser WorkflowCenterTreeData jsp node wftype 1 scope 2333 HTTP 1 1 Host Content T
  • 个人技术总结——uview-plus下的Http请求基本使用及相关使用

    这个作业属于哪个课程 软件工程 23年春季学期 这个作业要求在哪里 软件工程实践总结 个人技术总结 这个作业的目标 个人技术总结 其他参考文献 构建之法 CSDN社区 uni app官方文档 uview plus官方文档 目录 一 写在前面
  • vue发展历史简介

    基本介绍 Vue 是一套用于构建用户界面的 渐进式框架 与其它大型框架不同的是 Vue 被设计为可以自底向上逐层应用 最初它不过是个人项目 时至今日 已成为全世界三大前端框架之一 github 上拥有 17 8万 Star 领先于 Reac
  • mapState的使用(常用)

    mapState作用 可以辅助获取到多个state的值 怎么使用 1 在 vue组件中引入 在js块中引入 import mapState from vuex 2 在 vue组件中computed下定义一个对象 computed mapSt
  • Go中 Redis Client的使用

    文章目录 常见操作 List 操作 Pipeline 使用 在 Go 语言中使用 Redis 时 可以使用第三方库实现 Redis Client 的封装 本文介绍如何使用 Go 语言的 redisClient 去连接 Redis 服务器 并
  • Vue中数组的常用方法

    数组的方法分为变更方法和替换数组 变更方法 push push 方法可向数组的末尾添加一个或多个元素 并返回新的长度 pop pop 方法用于删除数组的最后一个元素并返回删除的元素 改变数组的长度 shift shift 方法用于把数组的第
  • 通过JSP网页连接并读取MySQL数据库中的表

    学习任务要求 配置JDBC使JSP网页能连接MYSQL数据库 用Navicat Premium在MYSQL数据库中建立一张表 在连接好后的JSP网页中显示出MYSQL数据库中的表 前言 在前面 我们已经学习了如何建立 发布和访问JSP网页
  • windows下如何禁止某个特定的应用程序

    windows下如何禁止某个特定的应用程序 最近 想了下如何禁止打开windows下的特定应用程序 查阅资料后终于解决了 下面把具体方法分享给大家 以禁止当前主流游戏 英雄联盟为例 1 win R打开运行栏 输入gpedit msc 2 点
  • 基于SSM框架实现一个用户系统(登录,用户列表,分页,增删改查,用户角色管理功能)

    首先搭建一个Maven工程 配置好Tomcat mybatis等 数据库 tb role tb user user role 这里只给了第一个用户管理员限权 可以对其他用户添加管理员 必须要用第一个用户登录 bean 这三个就不用多说了 直
  • MVC三层架构

    1 MVC三层架构 MVC Model View Controller 是一种常见的软件设计模式 用于组织和管理应用程序的代码和逻辑 它将应用程序分为三个主要部分 模型 Model 视图 View 和控制器 Controller 每个部分都
  • MOS管原理-1

    P型半导体参杂价电子为3的元素 一般为硼 因为硼的价电子比硅少一个 所以在共价键中少了一个电子 留下了空穴 空穴会吸引自由电子过来 入住 所以参与导电的是空穴 N型半导体参杂价电子为5的元素 一般为砷 因为砷的价电子比硅多一个 所以在N型半
  • Java Word转PDF

    两种方式 documents4j groupdocs 一 documents4j 1 添加依赖
  • Springer独立出版

    会议简介 Brief Introduction 2023年触觉与虚拟现实国际会议 ICHVR 2023 会议时间 2023年12月15日 17日 召开地点 中国 北海 大会官网 www ichvr org 2023年触觉与虚拟现实国际会议
  • C++ primer目录

    目录 第1章 快速入门 1 1 编写简单的C 程序 1 2 初窥输入 输出 1 2 1 标准输入与输出对象 1 2 2 一个使用IO库的程序 1 3 关于注释 1 4 控制结构 1 4 1 while语句 1 4 2 for 语句 1 4
  • IT痴汉的工作现状26-好项目,坏项目

    塞翁失马焉知非福 淮南子 人间训 祸兮 福之所倚 福兮 祸之所伏 老子 命运就是这样 当他给你关闭一扇门的同时也为你打开了另一扇门 同样 当他给你打开一扇门的同时也为你关闭了一扇门 有些事情 我们要用辩证的观点去看 人生如此 项目亦如此 伟
  • 数学建模——论文排版

    目录 一 参考文献的排版 1 三种方案 通常使用方案一 方案一有两种方法 2 参考文献排版要点总结 二 附录的排版 具体方法 补充 代码高亮 三 表格标题自动编号 进阶做法 四 公式编辑软件的介绍 1 LaTeX 较难 有时间可学 2 wo
  • AI会议排名_周志华

    AI会议排名 周志华 http blog sina com cn s blog 631a4cc40100xl7d html 南京大学周志华教授写的一个很经典的帖子 不过IJCAI能不能算成是no 1的会议有待商榷 不过总体还算客观 说明 纯
  • Dubbo远程传输协议详解

    前言 上次小编为大家带来了Dubbo调用及容错机制详解 不知道大家有没有去看小编最后留下的问题 欢迎对文章进行评论也希望大家和小编多多交流 今天接着为大家带来Dubbo的内容 传输协议 上次调用机制中并没有涉及Dubbo传输的协议 这次容小