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


相关推荐

  • 非正交多址接入(NOMA)与层分复用(LDM)

    非正交多址接入(NOMA)与层分复用(LDM)功率域 NOMA 及其应用实例 ATSC3 0 中的层分复用 LDM

    2026年3月18日
    2
  • oracle到hive数据类型转换「建议收藏」

    oracle到hive数据类型转换「建议收藏」oracle和hive中的数据类型存在差异,在oracle集成数据到hive中这样的场景下,我们希望在hive中的数据是贴源的,所以在hive中希望创建和oracle结构一致的表。oracle到hive数据类型映射参考如下:selectcasewhent1.column_id=1then’CREATETABLEIFNOTEXISTS’||’project’||’….

    2026年2月8日
    6
  • Could not get a resource from the pool 问题解决

    Could not get a resource from the pool 问题解决Couldnotgetaresourcefromthepool问题解决今天测试项目的时候,界面提示Couldnotgetaresourcefromthepool报错信息。登录后台,查询对应的java报错日志报错信息:redis.clients.jedis.exceptions.JedisConnectionException:Couldnotgetaresourcefromthepool到这里可以确定的是redis连接出了问题。..

    2025年7月29日
    10
  • MySQL基础day06_mysql服务器的主从同步-MySQL 5.6

    MySQL基础day06_mysql服务器的主从同步-MySQL 5.6mysql 服务器的主从同步实例环境 server1192 168 1 200server219 168 1 110 环境部署 1 首先保证服务器在同一个网段 能够互相连通 2 确保防火墙 selinux 关闭 root server1 iptables F 清空防火墙列表 root s

    2026年3月26日
    2
  • OpenClaw 中文版部署全流程实战(含经验分享)

    OpenClaw 中文版部署全流程实战(含经验分享)

    2026年3月12日
    5
  • QString与char *的相互转换

    QString与char *的相互转换在进行编程时,我们经常需要用到字符串这种类型,毫无疑问,Qt库中也对字符串类型进行了封装,QString类提供了你能想到的所有字符串操作方法,给开发者带来了极大方便。  但是我们在编写程序时,不可避免地会在Qt框架上使用第三方的开源库,由于库的类型基本上都是标准的类型,即使用char*来表示字符串类型。那么问题来了,QString和char*之间如何进行转换呢?  下面分两

    2022年5月12日
    35

发表回复

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

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