Skip to content

Conversation

@Q1ngbo
Copy link
Contributor

@Q1ngbo Q1ngbo commented Jan 15, 2026

What problem does this PR solve?

Issue Number: #3062 #3196

Problem Summary:
Hi, 本提交添加了对flatbuffers协议的完整支持。我增加了与“baidu_std”并列的协议,暂时命名为“fb_rpc”,主要实现在文件flatbuffers_protocol.cpp/h中。我认为以下2点值得关注:

  1. 类似于pb协议(即"baidu_std")的CallMethod,fb协议的请求起始于FBCallMethod,但二者十分相似,仅有几行差异,所以我使用函数模板CallMethodInternal提取了二者中的公共部分,使用参数is_pb区分,CallMethod传入参数为true,FBCallMethod为false。较宏观的benchmark测试显示修改后对pb协议几乎没有影响。
  2. Protocol类中的SerializeRequest和PackRequest这两个hook将形参固定为了google::protobuf类型,为了支持fb协议,我将它们改为了void*类型,并对所有协议中的这两个hook进行了适配,在对应函数开头加上了类型转换。

由于该提交依赖于#3196,且编译机器上未安装flatbuffers,所以本pr暂时无法直接编译。我计划根据评审老师的意见再进行修改并添加单测等完整实现。

Check List:

Key components:
- Protocol Implementation
  * Added flatbuffers_protocol.cpp/h for parsing, serialization and
     request/response handling.
  * Registered "fb_rpc" protocol in global.cpp
- Core Infrastructure Updates
  * Channel: Added FBCallMethod and CallMethodInternal<bool is_pb>
     template for dual pb/fb support.
  * Controller: Added _fb_method, _fb_response fields and
     is_use_flatbuffer() method for flatbuffers state tracking.
  * Server: Added FlatBuffersMethodProperty/ServiceProperty structures
     and AddService() overloads for flatbuffers::Service registration.
- Protocol Handler Refactoring
  * Updated all protocol handlers (baidu_rpc, http, http2, redis, etc.)
     to use generic void* pointers instead of google::protobuf types,
     enabling protocol-agnostic message handling.
@Q1ngbo
Copy link
Contributor Author

Q1ngbo commented Jan 15, 2026

补充内容

fb协议处理的简要说明

Client应用会创建Stub,然后调用fbs中指定的method方法,之后会去调用channel->FBCallMethod。这些方法都是由flatbuffers自动生成的,而FBCallMethod是在brpc中定义的,此处是二者间的一个桥梁。由于FBCallMethod的实现与针对pb协议的CallMethod非常类似,所以我使用函数模板CallMethodInternal提取了二者中的公共部分,使用参数is_pb区分,CallMethod传入参数为true,FBCallMethod为false。发送路径上的序列化(SerializeFlatBuffersRequest)、Pack(PackFlatBuffersRequest)等操作已经被定义在了Protocol fb_protocol中。

序列化函数SerializeFlatBuffersRequest的执行逻辑非常简单,首先根据FBRpcRequestHeader大小来调整message前面预留的header buffer空间,然后零拷贝地将message中的SingleIOBuf append至目的IOBuf就结束了。值得注意的是,fb协议中header的各字段被硬编码了,不能像pb一样通过proto文件(baidu_rpc_meta.proto)调整。

函数PackFlatBuffersRequest的功能与baidu_std协议中的PackRpcRequest函数类似,只不过rpc header部分已经预先分配好。

Server应创建一个类,继承fb.h中生成的Service,并重载其virtual方法。在启动Server进程时,应将该类对象通过AddService将该service注册至brpc。接收到的请求会交由ProcessFlatBuffersRequest处理,它首先从msg->meta中提取出Header(这一步由SingleIOBuf::assign完成,可能会有拷贝);然后配置Controller,从msg->payload中解析出fb message(同样会调用SingleIOBuf::assign);交由应用响应。应用逻辑处理完成后,会通过SendFlatBuffersRpcResponse向Client发送response message,这里同样会将rpc header + message零拷贝地append到待发送IOBuf中。

性能测试

我基于multi_threaded_echo_c++改造了benchmark程序,分别基于pb和fb协议实现,benchmark_fb的实现在#3196中。该程序基于bthread模型,共享同一个channel;每次发送时创建message,该message包含32B固定字段+ string组成的浮动字段(由request_size指定),proto文件定义如下;采用同步发送;输出指标包括延迟和QPS。

syntax="proto2";
option cc_generic_services = true;

package test;

message BenchmarkRequest {
    required int32 opcode = 1;
    required int32 echo_attachment = 2;
    required int64 attachment_size = 3;
    required int64 request_id = 4;
    optional int64 reserved = 5;
    optional string message = 4;
};

message BenchmarkResponse {
    required int32 opcode = 1;
    required int32 echo_attachment = 2;
    required int64 attachment_size = 3;
    required int64 request_id = 4;
    optional int64 reserved = 5;
    optional string message = 4;
};

service BenchmarkService {
      rpc Test(BenchmarkRequest) returns (BenchmarkResponse);
};

测试目的是为了说明fb的处理效率优于pb。为了避免网络影响,测试在同机上进行,分别为client和server绑定4个核。
下表所示数据为thread_num=1,即bthread数目为1时的结果。测试过程中使用Req Size变化请求中的string长度来改变message总大小,由于message中包含32B的固定整数部分,所以message实际总大小为32B(固定部分) + Req Size,attachment为0。测试程序执行20s,记录平均QPS,单位为千次/秒。表格中pb(old)为原CallMethod实现,pb(new)为当前pr中基于函数模板CallMethodInternal的实现。表中最后一行展示的是fb相对于pb(new)的提升百分比,从该结果可知fb相对于pb有20~30%的性能提升,且使用函数模板后对pb几乎没影响。

协议\Req Size 0B 32B 64B 128B 256B 512B 1024B 2048B 4096B 8192B
pb(old) 45k 46k 45k 45k 45k 45k 42k 41k 39k 33k
pb(new) 46k 46k 47k 46k 45k 44k 43k 41k 39k 34k
fb 58k 58k 58k 58k 57k 57k 55k 52k 48k 43k
fb相对pb提升百分比 26.1% 26.1% 23.4% 26.1% 26.7% 29.5% 27.9% 26.8% 23.1% 26.5%

下表所示为thread_num=64,即并发bthread数目为64的测试结果,可以看到即使message大小为8KB,fb的提升仍有20.4%。

协议\Req Size 0B 32B 64B 128B 256B 512B 1024B 2048B 4096B 8192B
pb(old) 526k 522k 519k 511k 492k 471k 441k 397k 348k 282k
pb(new) 531k 521k 519k 515k 490k 470k 440k 399k 340k 279k
fb 649k 652k 650k 641k 615k 586k 550k 498k 416k 336k
fb相对pb提升百分比 22.2% 27.3% 25.2% 24.5% 25.5% 24.7% 25% 24.8% 22.4% 20.4%

另外测试发现即使携带attachment,仍能保持相近的提升百分比,因为attachment不会被序列化。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant