
Protocol Buffers(简称 Protobuf)是 Google 开发的一种语言无关、平台无关、可扩展的序列化数据结构的机制。它比 XML 和 JSON 更小、更快、更简单。
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}singular: 单个值(默认)repeated: 数组/列表map<K, V>: 键值对.proto 类型 | C++ 类型 | Java 类型 | Python 类型 |
|---|---|---|---|
double | double | double | float |
float | float | float | float |
int32 | int32 | int | int |
int64 | int64 | long | int/long |
bool | bool | boolean | bool |
string | string | String | str |
bytes | string | ByteString | bytes |
// proto2
syntax = "proto2";
message Example {
required string name = 1; // 必须字段
optional int32 id = 2; // 可选字段
repeated string emails = 3; // 重复字段
}
// proto3
syntax = "proto3";
message Example {
string name = 1; // 默认都是可选
int32 id = 2;
repeated string emails = 3;
}message SampleMessage {
oneof test_oneof {
string name = 1;
int32 id = 2;
}
}message Product {
map<string, string> properties = 1;
}message Outer {
message Inner {
string text = 1;
}
Inner inner = 1;
}import "other.proto";package my.package;
// Java 特定选项
option java_package = "com.example.generated";
option java_outer_classname = "ExampleProto";syntax = "proto3";
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}import addressbook_pb2
# 创建消息
person = addressbook_pb2.Person()
person.id = 1234
person.name = "John Doe"
person.email = "jdoe@example.com"
phone = person.phones.add()
phone.number = "555-4321"
phone.type = addressbook_pb2.Person.HOME
# 序列化
serialized_data = person.SerializeToString()
# 反序列化
new_person = addressbook_pb2.Person()
new_person.ParseFromString(serialized_data)
print(f"Name: {new_person.name}")
print(f"Email: {new_person.email}")// 创建 Builder
Person person = Person.newBuilder()
.setId(1234)
.setName("John Doe")
.setEmail("jdoe@example.com")
.addPhones(
Person.PhoneNumber.newBuilder()
.setNumber("555-4321")
.setType(Person.PhoneType.HOME)
.build())
.build();
// 序列化
byte[] serializedData = person.toByteArray();
// 反序列化
Person newPerson = Person.parseFrom(serializedData);
System.out.println("Name: " + newPerson.getName());
System.out.println("Email: " + newPerson.getEmail());# 下载 protoc 编译器
# 或使用包管理器安装# 生成 Java 代码
protoc --java_out=. addressbook.proto
# 生成 Python 代码
protoc --python_out=. addressbook.proto
# 生成多种语言
protoc --java_out=. --python_out=. --cpp_out=. addressbook.protoreserved 声明message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}特性 | Protobuf | JSON | XML |
|---|---|---|---|
大小 | 小 | 大 | 很大 |
速度 | 快 | 慢 | 很慢 |
可读性 | 差 | 好 | 好 |
类型安全 | 强 | 弱 | 弱 |
跨语言 | 优秀 | 优秀 | 优秀 |
Protobuf 在现代分布式系统中扮演着重要角色,特别是在性能要求高、需要跨语言协作的场景中表现出色。