RSS

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

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

Flatbuffers 是一个序列化库,允许您访问序列化数据,而无需先解包或分配任何其他数据结构。它最初是为游戏和其他资源受限的应用程序设计的,但现在被 Google 内部的团队以及 Netflix 和 Facebook 等其他公司更广泛地使用。

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

目前,这在 FlatBuffers 的 C++ 实现中得到完全支持,未来会有更多语言支持。还有一个 Go 实现,它不是完全零拷贝的,但分配成本仍然非常低(见下文)。

使用示例

让我们看一个例子,说明它是如何工作的。

将 Flatbuffers 用作 IDL

首先从一个 .fbs 模式开始(类似于 .proto,如果您熟悉协议缓冲区),它声明了一个 RPC 服务

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,这与协议缓冲区非常相似。

生成的服务器实现

服务器实现与协议缓冲区非常相似,除了现在请求和响应消息的类型是 flatbuffers::grpc::Message<HelloRequest> *。与协议缓冲区(其中这些类型表示 C++ 对象树)不同,这里它们只是指向底层 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>();

客户端代码与协议缓冲区生成的代码相同,只是 FlatBuffer 访问和构造代码不同。

在此处查看完整示例here。要编译它,您需要 gRPC。相同的存储库有一个类似的 Go 示例

阅读更多关于为您的平台使用和构建 FlatBuffers 的信息在 flatbuffers 站点上