SRPC 是全搜狗以及腾讯部分业务线上使用的 RPC 框架,包括多种 IDL(protobuf/thrift)、多种 RPC 协议( srpc/brpc/thrift/tRPC ,且 tRPC 协议是唯一授权的开源版实现)、二进制协议与 HTTP 互转、支持多种压缩算法,AOP 模块化方式支持框架级数据上报(可对接 OpenTelemetry )。
以上这些层次都在同一套代码里,用了多种多态的方式互通每层的不同类功能,架构整体是解耦合的,因此代码很短只有一万多行。接口上用了代码生成,rpc 接口比 protobuf 原生简单,且 thrift 纯自解析、接口与原生兼容。轻量级的体现除了代码精简以外,还有依赖少、编译快(单核编译 32 秒)、体积小( strip -S 后 1.4M )、内存小(示例 server 跑起来 4M )。
目前每天上百亿的请求量,涵盖搜广推业务,稳定且性能好。虽然企业级的应用几十万 QPS 也是基操,但更重要的还是高 QPS 下保证请求延迟的稳定性。另外支持 Windows ,发现使用者中用 Windows 的占比还不小。
Proto 文件:
syntax = "proto3"; // both proto2 and proto3 are supported message EchoRequest { string message = 1; string name = 2; }; message EchoResponse { string message = 1; }; service Example { rpc Echo(EchoRequest) returns (EchoResponse); }; Server 实现:
#include <stdio.h> #include <signal.h> #includ "example.srpc.h" using namespace srpc; class ExampleServiceImpl : public Example::Service { public: void Echo(EchoRequest *request, EchoResponse *response, RPCContext *ctx) override { response->set_message("Hi, " + request->name()); } }; int main() { SRPCServer server_tcp; SRPCHttpServer server_http; // 同时启动一个 http server ExampleServiceImpl impl; server_tcp.add_service(&impl); // 同一份实现可以加到多种协议的 server 中 server_http.add_service(&impl); server_tcp.start(1412); server_http.start(8811); getchar(); // press "Enter" to end. server_http.stop(); server_tcp.stop(); return 0; } Client 调用:
#include <stdio.h> #include "example.srpc.h" using namespace srpc; int main() { Example::SRPCClient client("127.0.0.1", 1412); EchoRequest req; req.set_message("Hello, srpc!"); req.set_name("v2ex"); client.Echo(&req, [](EchoResponse *response, RPCContext *ctx) { if (ctx->success()) printf("%s\n", response->DebugString().c_str()); }); getchar(); // press "Enter" to end. return 0; } 也可以用 curl 直接发 http 请求到 http server 中:
curl 127.0.0.1:8811/Example/Echo -H 'Content-Type: application/json' -d '{message:"Hello, srpc!",name:"CURL"}' 由于 SRPC 定位很轻量级,目前我们也在继续往周边生态探索和建设中。项目主页有 benchmark 、wiki 以及 tutorial 现成示例,欢迎大家提出宝贵的建议。
