轻量级RPC分布式网络通信框架设计——序列化协议Protobuf

01 序列化协议对比

  • 序列化:对象转为字节序列称为对象的序列化
  • 反序列化:字节序列转为对象称为对象的反序列化

image-20220814235216125

常见序列化和反序列化协议有XML、JSON、PB,相比于其他PB更有优势:跨平台语言支持,序列化和反序列化效率高速度快,且序列化后体积比XML和JSON都小很多,适合网络传输。

XMLJSONPB
保存方式文本文本二进制
可读性较好较好不可读
解析效率一般
语言支持所有语言所有语言C++/Java/Python及第三方支持
适用范围文件存储、数据交互文件存储、数据交互文件存储、数据交互

注意:序列化和反序列化可能对系统的消耗较大,因此原则是:远程调用函数传入参数和返回值对象要尽量简单,具体来说应避免:

远程调用函数传入参数和返回值对象体积较大,如传入参数是List或Map,序列化后字节长度较长,对网络负担较大
远程调用函数传入参数和返回值对象有复杂关系,传入参数和返回值对象有复杂的嵌套、包含、聚合关系等,性能开销大
远程调用函数传入参数和返回值对象继承关系复杂,性能开销大

02 源码解析

  • 比其他序列化语言 更小 更快 更简单

  • 每定义一个message 都会生成一个类 每一个message里面的变量 bytes int32 bool 都会生成对应的方法 set_name() set_pwd()

  • 使用版本proto3

  • 编译结束后,会生成一个.h和一个.cc文件

src/rpcheader.proto

syntax = "proto3"
package mprpc;

message RpcHeader {
	bytes service_name = 1;
	bytes method_name = 2;
	uint32 args_size = 3;
}

example/user.proto

syntax = "proto3"

package fixbug;

option cc_generic_services = true;

message ResultCode {
	int32 errcode = 1;
	bytes errmsg = 2;
}

message LoginRequest {
	bytes name = 1;
	bytes pwd = 2;
}

message LoginResponse {
	ResultCode result = 1;
	bool success = 2;
}

service UserServiceRpc {
	rpc Login(LoginRequest) returns(LoginResponse);
}

//编译指令 protoc user.proto -cpp_out=./

03 Protobuf实现原理

img

上面说了protobuf的message中有很多字段,每个字段的格式为:
修饰符 字段类型 字段名 = 域号;
在序列化时,protobuf按照TLV的格式序列化每一个字段,T即Tag,也叫Key;V是该字段对应的值value;L是Value的长度,如果一个字段是整形,这个L部分会省略。
序列化后的Value是按原样保存到字符串或者文件中,Key按照一定的转换条件保存起来,序列化后的结果就是 KeyValueKeyValue…。Key的序列化格式是按照message中字段后面的域号与字段类型来转换。

04 粘包问题解决

image-20220815120520672

定义protobuf类型的结构体消息RpcHeader,包含服务对象、函数方法、函数参数,因为参数可变,参数长不定,因此不能和RpcHeader一起定义,否则多少函数就有多少RpcHeader,因此需为每个函数定义不同protobuf结构体消息,然后对该结构体消息序列化(字符串形式存储),就得到两个序列化后的二进制字符串,拼接起来就是要发送的消息,同时消息前需记录序列化后的RpcHeader数据的长度,这样才能分开RpcHeader和函数参数的二进制数据,从而反序列化得到函数参数
序列化后的二进制字符串,拼接起来就是要发送的消息,同时消息前需记录序列化后的RpcHeader数据的长度,这样才能分开RpcHeader和函数参数的二进制数据,从而反序列化得到函数参数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-特立独行的猪-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值