Protobuf 和 gRPC

1、概览

在软件开发中,微服务架构已成为创建可扩展和可维护系统的一种受欢迎的方法。在微服务之间进行有效的通信至关重要,其中涉及的技术包括 REST、消息队列、Protocol Buffer(Protobuf)和 gRPC等。

本文将重点介绍 Protobuf 和 gRPC,研究它们的异同、优缺点,从而全面了解它们在微服务架构中的作用。

2、Protobuf

Protocol Buffer 是一种不依赖语言和平台的结构化数据序列化和反序列化机制。其创建者谷歌宣称,与 XML 和 JSON 等其他类型的 Payload 相比,Protocol Buffer 更快、更小、更简单。

Protobuf 使用 .proto 文件来定义数据的结构。每个文件都描述了可能从一个节点传输到另一个节点或存储在数据源中的数据。定义了 Schema 后,就可以使用 Protobuf 编译器(protoc)生成各种语言的源代码:

syntax = "proto3"
message Person {
    string name = 1;
    int32 id = 2;
    string email = 3;
}

这是一个有三个字段的 Person 类型的简单消息协议。nameemailString 类型,而 id 是整数类型。

2.1、Protobuf 的优势

来看看使用 Protobuf 的一些优势。

Protobuf 数据结构紧凑,易于序列化和反序列化,因此在速度和存储方面都非常高效。

Protobuf 支持多种编程语言,如 Java、C++、Python、Go 等,促进了无缝跨平台数据交换。

它还能在不中断已部署程序的情况下添加或删除数据结构中的字段,从而实现无缝版本控制和更新。

2.2、Protobuf 的劣势

Protobuf 数据不是人类可读的,这就使得在不使用专门工具的情况下进行调试变得更加复杂。此外,与 JSON 或 XML 等格式相比,Protobuf Scheme 的初始设置和理解更为复杂。

3、gRPC

gRPC 是一个高性能的开源 RPC 框架,最初由谷歌开发。它有助于消除模板代码,并在数据中心内外连接多语言服务。我们可以将 gRPC 视 为REST、SOAP 或 GraphQL 的替代方案,它建立在 HTTP/2 的基础上,可以使用多路复用或流式连接等功能。

在 gRPC 中,Protobuf 是默认的接口定义语言(IDL),这意味着 gRPC 服务是使用 Protobuf 定义的。客户端可以调用服务定义中包含的 RPC 方法。protoc 编译器会根据服务定义生成客户端和服务端代码:

syntax = "proto3";

service PersonService {
  rpc GetPerson (PersonRequest) returns (PersonResponse);
}

message PersonRequest {
  int32 id = 1;
}

message PersonResponse {
  string name = 1;
  string email = 2;
}

在上例中,PersonService 服务被定义为一个获取 PersonRequest 消息并返回 PersonResponse 消息的 GetPerson RPC 方法。

3.1、gRPC 的优势

gRPC 的一些优势如下:

  • 利用 HTTP/2,它提供了 Header 压缩、多路复用和高效的二进制数据传输,从而降低了延迟,提高了吞吐量。
  • 由于它可以根据服务定义(Service Definition)自动生成各种语言的客户端和服务器存根(Stub),因此实现起来非常容易。
  • 由于支持客户端、服务器端和双向流,因此适用于实时数据交换。

3.2、gRPC 的劣势

现在,来看看使用 gRPC 所面临的一些挑战。

为简单的 CRUD 操作或轻量级应用设置 gRPC 可能并不合理,因为还有更简单的替代方案,比如使用 JSON 的 REST。和 Protobuf 一样,gRPC 也是二进制协议,如果没有合适的工具,调试起来会更加困难。

4、Protobuf 和 gRPC 的比较

要比较 Protocol Buffer(Protobuf)和 gRPC,我们可以使用一个类比:Protobuf 就像是一种设计用于高效打包旅行行李的语言。而 gRPC 则类似于一个全面的旅行社,负责从订购航班到安排交通等一切事宜,使用 Protobuf 的行李箱来携带我们的行李。

Protobuf 和 gRPC 的异同:

方面 Protobuf gRPC
开发商 由谷歌开发 由谷歌开发
使用的文件 使用 .proto 文件定义数据结构 使用 .proto 文件定义服务方法及其请求/响应
可扩展性 设计具有可扩展性,可在不破坏现有实现的情况下添加新字段 设计具有可扩展性,允许在不破坏现有实现的情况下添加新方法
支持语言和平台 支持多种编程语言和平台,使其适用于不同的环境 支持多种编程语言和平台,使其适用于不同的环境
OSI 模型层 运行在第 6 层 在第 5、6 和 7 层运行
定义 只定义数据结构 允许在 .proto 文件中定义服务方法及其请求/响应
作用和功能 类似于 JSON 这样的序列化/反序列化工具 管理客户端和服务器之间交互的方式(类似于使用 REST API 的 Web 客户端/服务器)
流式传输支持 没有内置流式传输支持 支持流式传输,允许服务器和客户端进行实时通信

5、总结

本文介绍了 ProtobufgRPC。两者都是功能强大的工具,但它们的优势在不同的应用场景中各显神通。最佳选择取决于具体需求和优先级。在做决定时,应该考虑速度、效率、可读性和易用性之间的权衡。

我们可以使用 Protobuf 进行高效的数据序列化和交换,而当需要一个具有高级功能的成熟 RPC 框架时,可以选择 gRPC。


Ref:https://www.baeldung.com/java-protocol-buffer-grpc-differences