1、概述
dubbo 默认的 rpc 协议为 dubbo。
dubbo 协议分为 header、消息体 2 部分。
2、协议设计
请求协议:
响应协议:
3、编码
代码位置: ExchangeCodec#encode(Channel, ChannelBuffer, Object)
netty 网络层面的入口为:InternalEncoder#(ChannelHandlerContext, Object, ByteBuf)
编码过程将消息按照请求协议进行封装,逻辑简单,不过多说明。
4、解码
解码包含请求的解码、响应的解码
代码位置: DubboCodec#decodeBody(Channel, InputStream, byte[])
netty 网络层面的入口为:InternalDecoder
-
netty 的 IO 线程,只会做协议头的解码工作,具体的返回消息内容,不会做解码
代码位置:InternalDecoder#decode(ChannelHandlerContext, ByteBuf, List<Object>) -
最外层的解码工作完成后,会根据
decode.in.io参数判断,是否在 IO 线程做消息体的解码,默认不处理
代码位置:DubboCodec#decodeBody(Channel, InputStream, byte[])
-
netty 框架的 pipeline 将消息流转给
NettyClientHandler处理
代码位置:NettyClient#doOpen()
-
NettyClientHandler 的工作线程中,处理解码工作
代码位置:ChannelEventRunnable#run()
NettyClientHandler 的线程池,将任务放在ChannelEventRunnable中处理
结论
消息头会在IO 线程中解码消息体会在业务线程中解码, 其中,可以根据decode.in.io做控制,默认false
5、异常的序列化和反序列化
异常本身有实现序列化接口,因此可以轻松的被序列化、反序列化
6、注意事项
- dubbo 协议,请求、响应 至多 8m。可通过 url 上的
payload参数控制,单位 B
代码位置:AbstractCodec#checkPayload