文章导读
本文主要介绍gRPC中重要的部分Protocol Buffers,预计需要花费15分钟左右的时间,阅读后你将收获以下知识,
- Protocol Buffers(以下简称pb)的基本概念,pb和gRPC的关系。
- Protocol Buffers优缺点。
- Protocol Buffers的工作流。
这是一篇进阶版本的文章,读者应具备基本的gRPC基础,在此之前已有文章讲解Python3搭建gRPC(入门版),如不了解gRPC建议先阅读Python3搭建gRPC(入门版)
同时提供以下进阶材料
- Python3搭建gRPC(入门版)
- 同步视频教程(后续会更新)
- 其他相关联文章,包括pytest进行gRPC测试,python3客户端测试java/golang grpc服务端(后续会更新)
如果大家觉得有收获,记得一键三连,后续继续为大家输出更多有价值的文章!!!
Protocol Buffers是什么?
Protocol Buffers是一个跨语言,跨平台可扩展的数据结构序列化的一个工具语言,和JSON类似,但比JSON更小,更高效,通过Protocol Buffers提供的工具可以生成多种语言的源代码,可以轻松的构建接口入参,返回值以及序列化。
- 是一种接口描述语言(IDL=Interface Definition Language),用于进行接口的描述与定义
- 提供对应的工具,将pb转成多种语言的源码(比如Python,Golang)
- 通过对应的源码可以构造入参,读取返回值
客户端和服务端进行接口调用时,入参数据,返回值数据,调用哪个接口都是需要通过Protocol Buffers进行翻译,我们可以简单理解Protocol Buffers承担的就是翻译工作
Protocol Buffers目前支持的语言- C++,C#,Java,Kotlin,Objective-C,PHP,Python,Ruby,Dart,Go
比JSON更高效
为什么有了JSON,XML等序列化的工具和语言,为什么还需要pb(Protocol Buffers,文章后续都通过pb表示Protocol Buffers),相比于JSON,他有如下优点
- 紧凑型的数据存储,传输效率更高,后续会有文章介绍
- 解析速率快,比如接收到服务端数据,转换成客户端对应的语言数据速度快
- 适用于多种工程语言,适合在异构系统中使用
- 可以自动生成类,比如通过pb生成python/java/golang等
也有缺点
世界上没有任何一种语言和方案能解决所有的场景,所以就会存在多种编程语言,同样的,pb也有缺点
- pb倾向于一次性将整个消息放到缓存中,如果一次性返回的数据特别大可能会造成惊人的内存使用量
- pb并不会进行消息的压缩
- pb在消息大小支持和效率上都不是最佳的
- 非面向对象语言通常不会支持pb
- 强依赖proto文件,如果没有proto文件将无法解释这次请求
- 不属于标准组织的正式标准,比如http协议就是标准协议,但是protocal buffers不是标准协议
Protocol Buffers工作流程
1、创建以proto为后缀的文件,进行proto定义
# hello.proto
syntax = "proto3";
service Hello{
rpc SayHello (HelloRequest)
returns (HelloResponse){}
}
message HelloRequest{
string name = 1;
}
message HelloResponse{
string response = 1;
}
2、通过grpcio-tools或者protoc将pb编译成对应的语言,比如Python,Goland
python3 -m grpc_tools.protoc -I ./ --python_out=. --pyi_out=. --grpc_python_out=. hello.proto
grpc_tools.protoc命令参数解释
-I: 可以理解为include,指的是编译当前文件时,如果需要引入外部依赖的proto文件时,需要指定引入的目录,第5章会有详细介绍
--python_out: 生成的python源码存放路径
--pyi_out: 生成的pyi源码存放路径
--grpc_python_out: 生成的grpc_python存放路径
执行后会生成以下3个源码,源码具体作用第5章会详细讲解
3、编译服务端/客户端代码
将你开发的服务端代码/客户端代码进行编译,然后运行,如果是Python则不需要编译直接运行,因为Python是脚本型语言,Golang/Java等需要先编译
4、数据序列化工作
通过客户端进行调用,调用时入参的Python对象/Golang对象会被Protocol Buffers进行序列化成二进制流通过网络传输发送给服务端
Protocol Buffers的序列化在哪里完成的? 生成的hello_pb2.py,hello_pb2_grpc.py就是进行序列化的入口