深圳网站制作培训,wordpress在线商城插件,林州网站建设,中山seo关键词目录 前言特点语法定义关键字JSON与Protocol Buffers互相转换gRPC与Protocol Buffers的关系 前言
Protocol Buffers#xff08;通常简称为protobuf#xff09;是Google公司开发的一种数据描述语言#xff0c;它能够将结构化数据序列化#xff0c;可用于数据存储、通信协议… 目录 前言特点语法定义关键字JSON与Protocol Buffers互相转换gRPC与Protocol Buffers的关系 前言
Protocol Buffers通常简称为protobuf是Google公司开发的一种数据描述语言它能够将结构化数据序列化可用于数据存储、通信协议等方面。这种序列化格式很灵活、高效、自动化不依赖于语言和平台并且可扩展性极强。使用protobuf时您只需将数据结构定义一次使用.proto文件定义便可以使用特别生成的源代码轻松地使用不同的数据流完成对这些结构数据的读写操作即使使用不同的语言protobuf的跨语言支持特性。您甚至可以更新数据结构的定义就是更新.proto文件内容而不会破坏依赖“老”格式编译出来的程序。 特点
Protocol Buffers主要具有以下三大特点
语言无关 支持多种语言包括但不限于Java、Python、C、JavaScript、Go、Ruby、PHP、Objective-C、C#等。平台无关 可生成不同语言的代码并在任何环境中运行。性能好、扩展性好 序列化和反序列化性能相比 JSON 和 XML 等更快平均每秒可以处理 10 万条消息。在微服务场景中使用合适的序列化协议会大大提高系统的性能。 语法定义
Protocol BuffersProtobuf的语法主要包括以下几个部分
消息定义在 .proto 文件中定义消息消息由字段组成。字段有三种类型required、optional、repeated分别表示必须、可选和重复。
message Person {required string name 1;optional int32 id 2;repeated string email 3;
}枚举定义枚举类型允许你定义一组有限的可能的值。
enum PhoneType {MOBILE 0;HOME 1;WORK 2;
}服务定义服务允许你定义一组相互关联的RPC远程过程调用。
service HelloService {rpc SayHello (HelloRequest) returns (HelloReply) {}
}字段编号每个字段都有一个唯一的数字编号。这是必要的因为在解析过程中我们需要知道每个字段的顺序。在 .proto 文件中定义的每个字段都有默认值。例如int32 类型的字段默认值为 0。字段类型每个字段都有一个类型。例如string、int32、message 等。对于 message 类型的字段你需要在括号内定义该消息的类型。对于 repeated 类型的字段你可以将多个值放入一个列表中。例如Person 消息中的 email 字段可以包含一个电子邮件地址列表。服务调用在客户端代码中你可以使用生成的 stub 类来调用服务方法。例如你可以这样调用 SayHello 方法
HelloService.stub stub HelloServiceGrpc.newBlockingStub(channel);
HelloReply response stub.sayHello(HelloRequest.newBuilder().build());关键字
Protocol BuffersProtobuf的关键字包括
message代表实体结构由多个消息字段field组成。required表示该字段是必需的。optional表示该字段是可选的。repeated表示该字段的值是一个列表可以包含0个或多个元素。group用于组织多个字段但目前该关键字已被废弃应使用message。syntax用于指定协议版本号没有指定则默认为proto2版本。package相等于C中的命名空间为了防止名称冲突。import引入其他的proto文件可以使用其他proto文件中定义的消息类型。message用于定义消息类型相当于C中的struct。enum用于定义枚举类型相当于C中的enum。option用于设置消息字段的选项如default、packed等。extensions用于定义扩展消息字段可以在现有消息类型的基础上添加新的字段。rpc用于定义远程过程调用RPC服务。service用于定义服务接口。default 用于为字段设置默认值。packed 用于指示字段值应该进行压缩存储。max 用于指定枚举类型的最大值。value 用于指定枚举类型的值。returns 用于指定RPC服务的返回类型。
这些关键字在Protobuf中具有特定的含义和用途根据需要选择使用。 此外Protobuf中的字段定义包括数据类型、字段名称、字段规则等部分。每个字段的定义由一定的格式构成包括数据类型、字段名称、字段标识是必须定义的部分字段默认值部分在proto3版本中不再支持。 JSON与Protocol Buffers互相转换
与JSON的区别
Protocol Buffers与JSON的区别主要体现在以下三个方面
数据格式JSON是文本格式而protobuf是二进制格式。JSON数据冗余较大例如每条记录都需要包含CName和Gender据统计JSON格式的数据至少有20%左右是无效的。而protobuf用二进制编码数据且数据的格式是事先通过一个后缀名为.proto的文件指定的因此protobuf的数据信息相对较少。解析速度由于protobuf对message没有动态解析没有了动态解析的处理序列化速度自然快通常protobuf的序列化速度是JSON的10倍左右。功能JSON只是一种数据表示法而protobuf则提供模式类型建立文档强制正确的用法。 总的来说JSON和protobuf在数据格式、解析速度和功能上存在明显差异。具体选择使用哪种数据存储格式取决于具体的应用场景和需求。 互相转换案例
在Java中我们可以使用一些库来实现JSON与Protocol Buffers之间的相互转换。这里以Google的Protocol Buffers和Jackson库为例进行介绍。
首先确保你的项目中已经添加了Protocol Buffers和Jackson的依赖。如果你使用Maven可以在pom.xml文件中添加以下依赖
dependencies!-- Protocol Buffers --dependencygroupIdcom.google.protobuf/groupIdartifactIdprotobuf-java/artifactIdversion3.17.3/version !-- 请检查是否有更新的版本 --/dependency!-- Jackson --dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.13.0/version !-- 请检查是否有更新的版本 --/dependency
/dependenciesProtocol Buffers转JSON
首先我们需要将Protocol Buffers的消息转换为Java对象。假设我们有一个Person消息
syntax proto3;
package tutorial;message Person {string name 1;int32 id 2;string email 3;
}编译这个.proto文件生成Java代码。然后我们可以使用Jackson库将Java对象转换为JSON
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.util.JsonFormat;
import tutorial.PersonOuterClass.Person;public class ProtobufToJsonExample {public static void main(String[] args) throws Exception {Person person Person.newBuilder().setId(1234).setName(Alice).setEmail(aliceexample.com).build();ObjectMapper objectMapper new ObjectMapper();String jsonString JsonFormat.printer().print(person);System.out.println(jsonString); // 输出JSON字符串}
}JSON转Protocol Buffers
同样地我们可以将JSON字符串转换为Java对象后再将其转换为Protocol Buffers消息
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.protobuf.util.JsonFormat;
import tutorial.PersonOuterClass.Person;public class JsonToProtobufExample {public static void main(String[] args) throws Exception {String jsonString {\id\:1234,\name\:\Alice\,\email\:\aliceexample.com\};ObjectMapper objectMapper new ObjectMapper();Person person objectMapper.readValue(jsonString, Person.class);System.out.println(person); // 输出Person消息对象}
}在Java中使用Protocol Buffers可以方便地进行数据序列化和反序列化。以下是一个简单的使用案例
假设我们有一个Person消息类型包含姓名、年龄和电子邮件地址等字段。我们可以使用Protocol Buffers的Java API来序列化和反序列化这个消息类型。
首先我们需要定义Person消息类型的.proto文件如下所示
syntax proto3;package tutorial;message Person {string name 1;int32 age 2;string email 3;
}然后我们需要使用Protocol Buffers的编译器protoc将.proto文件编译成Java代码。命令如下
protoc --java_out./ ./person.proto这将生成一个PersonOuterClass.java和一个Person.java文件其中Person.java包含Person消息类型的定义和相关方法。我们可以将这些代码导入到我们的Java应用程序中。
接下来我们可以使用Java代码来序列化和反序列化Person消息类型。以下是一个简单的例子
import tutorial.PersonOuterClass.Person;
import com.google.protobuf.util.JsonFormat;public class PersonProtobufExample {public static void main(String[] args) throws Exception {// 创建一个Person对象Person person Person.newBuilder().setId(1234).setName(Alice).setEmail(aliceexample.com).build();// 将Person对象序列化为字节数组byte[] bytes person.toByteArray();// 将字节数组反序列化为Person对象Person deserializedPerson Person.parseFrom(bytes);// 输出反序列化后的Person对象System.out.println(deserializedPerson);}
}这个例子中我们创建了一个Person对象将其序列化为字节数组然后将字节数组反序列化为Person对象并输出反序列化后的Person对象。
gRPC与Protocol Buffers的关系
Protocol Buffersprotobuf是由 Google 开发的一种数据序列化协议类似于 XML、JSON、YAML 等它可以将结构化的数据序列化成字节流以便在网络上进行传输或存储到文件或数据库中。
gRPC 是一个高性能、开源、通用的 RPC远程过程调用框架它基于 protobuf 实现使用 protobuf 序列化协议来序列化和反序列化消息。gRPC 支持多种语言包括 Java、C、Python、Go、Ruby、PHP 等可以跨语言进行通信。
因此gRPC 和 Protocol Buffers 的关系是protobuf 是 gRPC 使用的一种数据序列化协议gRPC 利用 protobuf 将数据序列化成字节流以便在网络上进行传输或存储到文件或数据库中。同时gRPC 也提供了接口和工具使得用户可以方便地使用 protobuf 进行数据序列化和反序列化操作。
gRPC的简单介绍