dubbo协议报文消息格式

dubbo协议报文消息格式dubbo 默认采用 netty 进行网络传输 协议中对字节流的处理在 com alibaba dubbo remoting exchange codec ExchangeCode 类中 包含了对 request 请求的编码和解码 response 响应的编码和解码 dubbo 协议采用固定长度的消息头 16 字节 和不定长度的消息体来进行数据传输 消息头定义了 netty 在 IO 线程处理时需要的信息 协议的报文格式如下 dubbo message protocol header 消息头详解协议头是 16 字节

 

 

dubbo协议报文消息格式_第1张图片

dubbo_message_protocol_header

消息头详解

协议头是16字节的定长数据:

2byte magic:类似java字节码文件里的魔数,用来判断是不是dubbo协议的数据包。魔数是常量0xdabb 1byte 的消息标志位:16-20序列id,21 event,22 two way,23请求或响应标识 1byte 状态,当消息类型为响应时,设置响应状态。24-31位。状态位, 设置请求响应状态,dubbo定义了一些响应的类型。具体类型见com.alibaba.dubbo.remoting.exchange.Response 8byte 消息ID,long类型,32-95位。每一个请求的唯一识别id(由于采用异步通讯的方式,用来把请求request和返回的response对应上) 4byte 消息长度,96-127位。消息体 body 长度, int 类型,即记录Body Content有多少个字节。 

解码过程 ExchangeCodec->encode-> encodeRequest

public void encode(Channel channel, ChannelBuffer buffer, Object msg) throws IOException { if (msg instanceof Request) { encodeRequest(channel, buffer, (Request) msg); } else if (msg instanceof Response) { encodeResponse(channel, buffer, (Response) msg); } else { super.encode(channel, buffer, msg); } } 
 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. int savedWriteIndex = buffer.writerIndex(); buffer.writerIndex(savedWriteIndex + HEADER_LENGTH); 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(); if (out instanceof Cleanable) { ((Cleanable) out).cleanup(); } bos.flush(); bos.close(); int len = bos.writtenBytes(); checkPayload(channel, len); Bytes.int2bytes(len, header, 12); // write buffer.writerIndex(savedWriteIndex); buffer.writeBytes(header); // write header. buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len); } 

消息体详解

实现源码在DubboCodec.encodeRequestData(Channel channel, ObjectOutput out, Object data):

 protected void encodeRequestData(Channel channel, ObjectOutput out, Object data) throws IOException { RpcInvocation inv = (RpcInvocation) data; out.writeUTF(inv.getAttachment(Constants.DUBBO_VERSION_KEY, DUBBO_VERSION)); out.writeUTF(inv.getAttachment(Constants.PATH_KEY)); out.writeUTF(inv.getAttachment(Constants.VERSION_KEY)); out.writeUTF(inv.getMethodName()); out.writeUTF(ReflectUtils.getDesc(inv.getParameterTypes())); Object[] args = inv.getArguments(); if (args != null) for (int i = 0; i < args.length; i++) { out.writeObject(encodeInvocationArgument(channel, inv, i)); } out.writeObject(inv.getAttachments()); } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/231891.html原文链接:https://javaforall.net

(0)
上一篇 2025年11月15日 上午11:01
下一篇 2025年11月15日 上午11:22


相关推荐

  • Java list foreach_java的foreach

    Java list foreach_java的foreach例子://使用com.google.guava包创建集合List<String>list=Lists.newArrayList(“a”,”b”,”c”,”d”);//1、正常遍历list.forEach(item->System.out.println(item));//2、根据条件遍历list.forEach…

    2026年4月13日
    8
  • 万文多图之Pycharm的使用图解

    万文多图之Pycharm的使用图解文章目录 1 新建项目 2 窗口介绍 3 Pycharm 设置 4 Pycharm 菜单中的功能 1 新建项目 Pycharm 是根据项目组织的 项目相关的配置文件存放在项目文件夹下的 idea 文件夹 隐藏文件夹 中 新建环境可以通过 Virtualenv 进行创建 也可以通过 Conda 进行创建 下方状态栏如下所示说明 Pycharm 正在对选定的 Python 解释器进行索引工作 在这个过程中 Pycharm 的自动补全和代码高亮都暂时无效 2 窗口介绍新建文件 File 空文件 Dir

    2026年3月27日
    2
  • 建立本地数据库[通俗易懂]

    建立本地数据库[通俗易懂]首先下载安装MySQL,参考:http://www.runoob.com/mysql/mysql-install.html,安装完成后直接打开(安装过程中要求设置用户名和密码,此时输入的密码要记住,后面要使用)然后下载NavicatforMySQL,本人觉得这个比较简单,很适合初学者,安装完成之后点击File(文件)–新建文件,连接名可不填,主机名:localhost,用户名是安装MySQL…

    2022年6月1日
    36
  • Python中可迭代对象是什么?

    Python中可迭代对象是什么?Python 中可迭代对象 Iterable 并不是指某种具体的数据类型 它是指存储了元素的一个容器对象 且容器中的元素可以通过 iter 方法或 getitem 方法访问 iter 方法的作用是让对象可以用 for in 循环遍历 getitem 方法是让对象可以通过 实例名 index 的方式访问实例中的元素 老猿认为这两个方法的目的是 Python 实现一个通用

    2026年3月18日
    2
  • Python数模笔记-模拟退火算法(2)约束条件的处理

    Python数模笔记-模拟退火算法(2)约束条件的处理1 最优化与线性规划最优化问题的三要素是决策变量 目标函数和约束条件 线性规划 Linearprogra 是研究线性约束条件下线性目标函数的极值问题的优化方法 常用于解决利用现有的资源得到最优决策的问题 简单的线性规划问题可以用 Lingo 软件求解 Matlab Python 中也有求解线性规划问题的库函数或求解器 很容易学习和使用 并不需要用模拟退火算法 但是 由一般线性规划问题所衍生的整数规划 混合规划 0 1 规划 二次规划 非线性规划 组合优化问题 则并不是调用某个库函数都能处理

    2026年3月16日
    1
  • chrome安装vue调试工具

    chrome安装vue调试工具1 首先下载 VueDevtools 调试工具 https github com vuejs vue devtools tree v5 1 1 2 复制网址 在浏览器打开按照图示操作 3 下载成功后解压即可 如下图所示 4 解压后打开 cmd 命令切换到 G VueDevtools 工具 vue devtools 5 1 1 路径下 你们安装的路径自己切换 5 切换命令成功后使用命令 npminstall 下载 下载成功如下图所示 6 然后在 npmrunbuild 如下图所示 7

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号