RSS

宣布 Flatbuffers 序列化库对 gRPC 提供开箱即用支持

Flatbuffers 1.7版本的最新发布引入了对 gRPC 的真正开箱即用零拷贝支持。

Flatbuffers 是一个序列化库,它允许您在不先解包或分配任何额外数据结构的情况下访问序列化数据。它最初是为游戏和其他资源受限的应用程序设计的,但现在正得到更广泛的应用,无论是谷歌内部团队还是 Netflix 和 Facebook 等其他公司都在使用。

Flatbuffers 通过在常见用例中直接使用 gRPC 的切片缓冲区实现零拷贝,从而实现了最大吞吐量。传入的 RPC 可以直接从 gRPC 的内部缓冲区进行处理,并且构建新消息时将直接写入这些缓冲区,无需中间步骤。

目前,FlatBuffers 的 C++ 实现已完全支持此功能,更多语言将陆续支持。此外,Go 中也有一个实现,该实现并非完全零拷贝,但在分配成本方面仍然非常低(详见下文)。

示例用法

让我们来看看这是如何工作的示例。

将 Flatbuffers 用作 IDL

从一个声明 RPC 服务的 .fbs 模式开始(如果您熟悉 Protocol Buffers,这与 `.proto` 类似)

table HelloReply {
  message:string;
}

table HelloRequest {
  name:string;
}

table ManyHellosRequest {
  name:string;
  num_greetings:int;
}

rpc_service Greeter {
  SayHello(HelloRequest):HelloReply;
  SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
}

要从中生成 C++ 代码,请运行:flatc --cpp --grpc example.fbs,这与 Protocol Buffers 非常相似。

生成的服务器实现

服务器实现与 Protocol Buffers 非常相似,只是现在请求和响应消息的类型为 flatbuffers::grpc::Message<HelloRequest> *。与 Protocol Buffers 中这些类型表示 C++ 对象树不同,在 Flatbuffers 中,它们只是底层 gRPC 切片中扁平对象的句柄。您可以直接访问数据

auto request = request_msg->GetRoot();
auto name = request->name()->str();

构建响应也同样简单

auto msg_offset = mb_.CreateString("Hello, " + name);
auto hello_offset = CreateHelloReply(mb_, msg_offset);
mb_.Finish(hello_offset);
*response_msg = mb_.ReleaseMessage<HelloReply>();

客户端代码与 Protocol Buffers 生成的代码相同,除了 FlatBuffer 的访问和构造代码。

完整的示例请参见此处。要编译它,您需要 gRPC。相同的代码库中也有一个针对 Go 的类似示例

有关如何在您的平台上使用和构建 FlatBuffers 的更多信息,请访问 Flatbuffers 网站