宣布 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 站点上。