当前位置: 首页 > news >正文

Protocol Buffers (Protobuf) 详解

文章目录

  • Protocol Buffers (Protobuf) 详解
    • 1. 什么是 Protocol Buffers?
    • 2. 核心特性
      • 2.1优点
      • 2.2 缺点
    • 3. 基本语法
      • 3.1 基本消息定义
      • 3.2 字段规则
      • 3.3 数据类型
    • 4. 版本差异
      • proto2 vs proto3
    • 5. 高级特性
      • 5.1 Oneof
      • 5.2 Map
      • 5.3 嵌套消息
      • 5.4 导入其他文件
      • 5.5 包和命名空间
    • 6. 实际应用示例
      • 6.1 完整的 .proto 文件
      • 6.2 Python 使用示例
      • 6.3 Java 使用示例
    • 7. 编译和使用
      • 7.1 安装编译器
      • 7.2 编译 .proto 文件
    • 8. 最佳实践
      • 8.1 字段编号
      • 8.2 向后兼容
      • 8.3 版本管理
    • 9. 与其他序列化格式对比
    • 10. 使用场景

Protocol Buffers (Protobuf) 详解

1. 什么是 Protocol Buffers?

Protocol Buffers(简称 Protobuf)是 Google 开发的一种语言无关、平台无关、可扩展的序列化数据结构的机制。它比 XML 和 JSON 更小、更快、更简单。

2. 核心特性

2.1优点

  • 高效性:二进制格式,体积小,序列化/反序列化速度快
  • 跨语言:支持多种编程语言
  • 向前/向后兼容:通过字段编号机制实现
  • 代码生成:自动生成数据访问类
  • 结构化数据:强类型定义

2.2 缺点

  • 可读性差:二进制格式不易阅读
  • 需要预编译:需要预定义 .proto 文件

3. 基本语法

3.1 基本消息定义

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;
}

3.2 字段规则

  • singular: 单个值(默认)
  • repeated: 数组/列表
  • map<K, V>: 键值对

3.3 数据类型

.proto 类型C++ 类型Java 类型Python 类型
doubledoubledoublefloat
floatfloatfloatfloat
int32int32intint
int64int64longint/long
boolboolbooleanbool
stringstringStringstr
bytesstringByteStringbytes

4. 版本差异

proto2 vs proto3

// 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;
}

5. 高级特性

5.1 Oneof

message SampleMessage {oneof test_oneof {string name = 1;int32 id = 2;}
}

5.2 Map

message Product {map<string, string> properties = 1;
}

5.3 嵌套消息

message Outer {message Inner {string text = 1;}Inner inner = 1;
}

5.4 导入其他文件

import "other.proto";

5.5 包和命名空间

package my.package;// Java 特定选项
option java_package = "com.example.generated";
option java_outer_classname = "ExampleProto";

6. 实际应用示例

6.1 完整的 .proto 文件

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;
}

6.2 Python 使用示例

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}")

6.3 Java 使用示例

// 创建 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());

7. 编译和使用

7.1 安装编译器

# 下载 protoc 编译器
# 或使用包管理器安装

7.2 编译 .proto 文件

# 生成 Java 代码
protoc --java_out=. addressbook.proto# 生成 Python 代码
protoc --python_out=. addressbook.proto# 生成多种语言
protoc --java_out=. --python_out=. --cpp_out=. addressbook.proto

8. 最佳实践

8.1 字段编号

  • 使用 1-15 作为常用字段(占用 1 字节)
  • 16-2047 作为不常用字段
  • 不要随意更改字段编号

8.2 向后兼容

  • 不要删除已使用的字段编号
  • 新字段使用新的编号
  • 已删除的字段可添加 reserved 声明
message Foo {reserved 2, 15, 9 to 11;reserved "foo", "bar";
}

8.3 版本管理

  • 在文件名或包名中包含版本信息
  • 使用语义化版本控制

9. 与其他序列化格式对比

特性ProtobufJSONXML
大小很大
速度很慢
可读性
类型安全
跨语言优秀优秀优秀

10. 使用场景

  • 微服务通信:gRPC 的默认序列化格式
  • 数据存储:高效存储结构化数据
  • 配置文件:强类型的配置定义
  • API 设计:定义清晰的接口契约

Protobuf 在现代分布式系统中扮演着重要角色,特别是在性能要求高、需要跨语言协作的场景中表现出色。

http://www.dtcms.com/a/617637.html

相关文章:

  • 沁水网站建设吉林省 网站建设
  • 正能量晚上看的网站2021网站优化客户报表
  • 智慧交通自动驾驶场景道路异常检测数据集VOC+YOLO格式8302张6类别
  • 内联函数(Inline Functions)详细讲解
  • CentOS Stream 8 通过 Packstack 安装开源OpenStack(V版本)
  • 企业实训|自动驾驶中的图像处理与感知技术——某央企汽车集团
  • 电子商城网站建设流程外链系统
  • 数据分析笔记10:数据容器
  • 基于Django的博客系统
  • 地图引擎性能优化:解决3DTiles加载痛点的六大核心策略
  • 树莓派5-ubuntu24.04 LTS 使用python构建雷达驱动包
  • Django Nginx+uWSGI 安装配置指南
  • php网站建设培训班如何在word里做网站
  • 用Rust从零实现一个迷你Redis服务器
  • 图表设计 网站郑州汉狮做网站的公司
  • 详解高可用 SFTP 服务器搭建,适用于文档管理系统、监控系统数据、NFS、FTP、Git 仓库、Web 静态资源高可用服务器等等应用场景
  • 【故障排查】intel 服务器安装Win server 2019蓝屏解决方法
  • Vue入门到实战(day7):Vuex 与 Vue Router 深度解析,从原理到实战的前端状态与路由管理(附代码案例)
  • 3种数据模型的演变
  • Highcharts常见问题解析(5):可以在服务器上使用 Highcharts 吗?如何正确集成?
  • 用 Node.js 手动搭建 HTTP 服务器:从零开始的 Web 开发之旅!
  • 前端使用 React Query 管理“服务器状态”
  • 佛山cms建站帮人做兼职的网站
  • Spring Boot的web基础配置
  • 下载网站上的表格 怎么做天津市建设工程质量安全监督管理总队网站
  • 【Linux日新月异(八)】CentOS 7系统资源监控与排查深度指南:性能调优全景图
  • word中怎么查看插入的图片占用内存大小来压缩word文件整体大小
  • Flink CDC + MaxCompute用 MaxCompute Connector 打通实时入湖通道
  • 【AI 学习】AI Agent 开发进阶:架构、规划、记忆与工具编排
  • 二十三、Transformer架构详解