← 返回信息流
GitHub 热榜GitHub Trending · 日·1 小时前

Protocol Buffers (protobuf) —— Google 的高效数据序列化格式

原标题:protocolbuffers/protobuf
C++71,510 stars+11 今日

速览

Protocol Buffers 是一种语言无关、平台无关、可扩展的序列化结构数据机制,比 XML/JSON 更小、更快、更简单。它通过定义 `.proto` 文件来结构化数据,并自动生成多种语言的代码,适用于网络通信、配置文件、持久化存储等场景。

AI 深度解读

这是什么

Protocol Buffers(简称 protobuf)是 Google 开源的、与语言和平台无关的序列化结构化数据的机制。它通过 .proto 文件定义数据结构,然后生成多种编程语言(如 C++、Java、Python、Go、Rust 等)的代码,用于高效地读写序列化后的二进制数据。protobuf 的核心组成部分包括:协议编译器(protoc),用于编译 .proto 文件;以及各语言的 运行时库,负责序列化与反序列化。项目在 GitHub 上以 protocolbuffers/protobuf 托管,主语言为 C++,拥有超过 71000 颗星,是业界最广泛使用的序列化工具之一。

解决的问题

应用程序在跨语言、跨网络或跨进程通信时,需要将结构化数据(如对象、消息)转换为字节流以便传输或存储,并在接收端还原。传统方案如 JSON、XML 虽然可读性好,但存在以下问题:

  • 效率低:文本格式体积大,解析速度慢,占用 CPU 和内存资源高。
  • 类型安全弱:缺乏严格的类型约束,易因类型不匹配导致运行时错误。
  • 版本演进困难:字段增加或删除时,需要协调所有参与方更新解析逻辑,否则容易破坏兼容性。

protobuf 通过 二进制编码预定义 schema 解决了这些问题:它生成紧凑的二进制数据,解析速度极快;强制类型检查,编译期即可发现错误;内置的字段编号和可选/必选语义支持 向前与向后兼容,使得协议可以在不中断服务的前提下演进。

核心功能

  1. 定义数据结构:使用 .proto 文件定义消息类型,支持标量类型(int32、string、bool 等)、枚举、嵌套消息、map、oneof 等复杂结构。
  2. 代码生成:通过 protoc 编译器为 C++、Java、Python、Go、C#、Ruby、JavaScript、Objective-C、PHP、Dart、Rust 等 20+ 语言生成源码,开发者只需调用生成的类方法即可完成序列化/反序列化,无需手写解析逻辑。
  3. 序列化与反序列化:提供 SerializeToString()SerializeToArray() 等接口写入字节流,以及 ParseFromString()ParseFromArray() 等接口还原对象。
  4. 版本兼容性:支持 optionalrequiredrepeated 字段,以及 reserved 关键字防止字段编号冲突。通过维护字段编号而非名称,允许在消息中添加/删除字段而不破坏现有代码。
  5. 扩展机制:支持 extensionsAny 类型,允许在未知字段中传递任意类型数据,适合动态扩展场景。
  6. 跨语言互操作:不同语言生成的 protobuf 对象可以互相序列化和反序列化同一二进制流,只要 .proto 文件一致。
  7. 与 gRPC 深度集成:protobuf 是 gRPC 的默认序列化格式,支持高效的服务定义和 RPC 调用。

亮点 / 与同类相比

  • 性能远超 JSON/XML:protobuf 编码后的体积通常比 JSON 小 3-10 倍,序列化/反序列化速度高 10-100 倍。例如,同样表示一个用户对象,protobuf 二进制只有几十字节,而 JSON 可能上百字节。
  • 强类型与编译期检查:与 JSON 的字符串键值对不同,protobuf 字段通过编号和类型绑定,类型错误在编译期即被捕获,显著减少运行时 bug。
  • 版本演进友好:Thrift 也支持 schema 演进,但 protobuf 的字段编号和 reserved 机制更简洁,且社区支持更广泛。与 Cap'n Proto 相比,protobuf 的生态更成熟,文档更完善。
  • 跨语言生态无与伦比:几乎所有主流语言都有官方或社区维护的 protobuf 运行时,且支持 C++、Java、Python 等语言的原生 JNI 或 ctypes 绑定,适合异构系统集成。
  • 工具链完善:protoc 支持多种插件(如 protoc-gen-goprotoc-gen-grpc),可扩展生成自定义代码。Bazel、CMake 等构建系统均提供官方支持,易于集成到大型项目。

适合谁用 / 上手

适合人群

  • 微服务架构开发者,需要跨语言、跨网络的高效数据传输。
  • 游戏、实时通信、物联网等对延迟和带宽敏感的场景。
  • 需要长期维护的 API 协议,希望避免因版本变动导致的服务中断。
  • 任何使用 gRPC 的团队(protobuf 是 gRPC 的默认序列化格式)。

上手步骤(以非 C++ 用户为例):

  1. 下载 protoc:从 GitHub Releases 下载对应平台的预编译二进制包(如 protoc-29.0-linux-x86_64.zip),解压后得到 protoc 可执行文件及标准 .proto 文件。
  2. 编写 .proto 文件:例如 person.proto
    syntax = "proto3";
    message Person {
      string name = 1;
      int32 id = 2;
      optional string email = 3;
    }
    
  3. 生成代码:运行 protoc --python_out=. person.proto 生成 Python 代码(或其他语言,如 --java_out--go_out)。
  4. 使用运行时库:在项目中安装对应语言的 protobuf 运行时库(如 Python 的 pip install protobuf),然后导入生成的模块,调用 SerializeToString()ParseFromString() 进行序列化/反序列化。

对于 C++ 用户,建议从源码构建 protoc,并遵循 C++ 安装指南。更详细的教程和示例可参考 官方开发指南

查看原文 →github.com