gRPC介绍
gRPC是一个高性能、开源且通用的RPC框架,它基于HTTP/2标准协议和Protocol Buffers进行数据序列化,支持多种编程语言。
rpc和http区别
- 传输协议:RPC可以基于TCP或HTTP协议,而HTTP服务则工作在HTTP协议之上。
- 效率和性能消耗:由于RPC可以使用自定义的TCP协议,请求报文体积可以更小,或者使用HTTP2协议来减少报文体积,从而提高传输效率。HTTP在1.1版本中可能包含较多无用信息,而2.0版本则可以简化封装,适合作为RPC使用。在性能消耗方面,RPC可以基于Thrift等高效二进制传输方式,而HTTP大多使用JSON,可能在字节大小和序列化耗时上更消耗性能。
ProtoBuf和json 对比
ProtoBuf在时间和空间效率上均优于JSON,具有显著的性能优势。
从时间效率上看,当处理的数据交换次数在2千以上时,ProtoBuf的编码和解码性能就已经比JSON高出很多。随着数据交换次数的增加,这种性能差异会变得更加明显。特别是在数据交换次数达到10万以上时,ProtoBuf的编解码性能远远高于JSON。这意味着在高频率的数据交互场景中,ProtoBuf能够提供更快的数据处理速度。
从空间效率上看,ProtoBuf的内存占用仅为JSON的三分之一左右。在一项对比测试中,ProtoBuf的内存占用为34,而JSON达到了106,这表明ProtoBuf在内存使用上更为高效。这在资源受限或者需要处理大量数据的场景中尤为重要,因为它可以减少系统资源的消耗。
综上所述,ProtoBuf在时间和空间效率上都表现出色,尤其是在数据量较大或处理频繁的场景下,其性能优势更加突出。这使得ProtoBuf成为了许多高性能数据交换场景的首选格式。
ProtoBuf优点
- 性能优异:ProtoBuf具有较小的数据体积,序列化后的数据大小可以缩小3-10倍。同时,它的序列化速度非常快,比XML和JSON快20-100倍。由于数据体积小,传输速度快,因此在带宽和速度方面会有优化。
- 使用简便:通过proto编译器,ProtoBuf可以自动进行序列化和反序列化操作,无需手动编写代码。
- 维护成本低:多平台只需维护一套对象协议文件(.proto),减少了在不同平台上的维护成本。
- 向后兼容性好:ProtoBuf支持对数据结构进行更新,而不必破坏旧数据格式,因此具有良好的向后兼容性。
- 加密性好:在Http传输中,抓包只能看到字节内容,无法直接查看明文信息,提高了数据的安全性。
- 跨平台、跨语言支持:ProtoBuf支持多种编程语言,包括Java, Python, Objective-C, C++, Dart, Go, Ruby, C#等,并且具有良好的可扩展性。
ProtoBuf的缺点
- 不适合用于对基于文本的标记文档(如HTML)建模,因为文本不适合描述数据结构。
- 通用性较差:虽然Json和Xml已成为多种行业标准的编写工具,但ProtoBuf只是Google公司内部的工具,其通用性相对较差。
- 自解耦性差:ProtoBuf以二进制数据流方式存储,无法直接阅读,需要通过.proto文件才能了解到数据结构。
- 阅读性差:生成出来的模型文件是不允许修改的(protoBuf官方建议),如果有新增字段,都必须依赖于.proto文件重新进行生成,导致生成出来的模型无论从可读性还是易用性上来说都是较差的。
proto文件基础介绍
Protocol Buffers(简称ProtoBuf)是Google开发的一种数据序列化协议,它能够将结构化数据序列化为二进制格式,用于数据存储或网络传输。以下是proto文件的基础介绍:
- 消息定义:在proto文件中,使用message关键字定义一个数据结构,这类似于C++中的class、Java中的Class或Go中的struct。消息中承载的数据对应于每个字段,每个字段都有一个名字和类型。
- 字段规则:
- required:表示必填字段,如果这些字段未设置,会导致编解码异常。
- optional:表示可选字段,对应生成的是指针类型。
- repeated:表示可重复字段,这些字段的值顺序会被保留,在Go中通常被定义为切片类型。
- 文件规范:创建proto文件时,应使用全小写字母命名,多个单词之间用下划线连接。例如:lower_snake_case.proto。书写代码时应使用2个空格的缩进。注释可以使用单行注释(//)或多行注释(/* */)。
- 语法指定:在文件首行指定该proto文件所采用的语法版本,如syntax = "proto3";表示使用proto3语法。
- 编解码原理:ProtoBuf通过Thrift编码和解码数据,这是一种紧凑的二进制格式,可以有效地用于网络传输和文件存储。
以下是一个简单的文件示例:
bash
syntax = "proto3";
message Error {
int32 code = 1;
string message = 2;
}
message Request {
string id = 1;
string data = 2;
}
message Response {
Error error = 1;
string result = 2;
}
service MyService {
rpc GetData (Request) returns (Response);
}
在上面的示例中,我们定义了一个名为MyService的service,它包含一个名为GetData的rpc方法。该方法接受一个Request类型的参数,并返回一个Response类型的结果。
通过这样的定义,我们可以使用proto生成对应语言的代码,以便在客户端和服务端之间进行RPC通信。客户端可以调用服务端上的GetData方法,并传递一个Request对象作为参数,服务端将返回一个Response对象作为结果。