ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

brpc 性能基准测试指南:面向长尾场景的 RPC 框架评测方法论与结果分析

brpc 性能基准测试指南:面向长尾场景的 RPC 框架评测方法论与结果分析 brpc 性能基准测试指南面向长尾场景的 RPC 框架评测方法论与结果分析【免费下载链接】brpcbrpc is an Industrial-grade RPC framework using C Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc. brpc means better RPC.项目地址: https://gitcode.com/GitHub_Trending/brpc/brpcbrpc 的官方基准测试文档见 docs/cn/benchmark.md回答了一个核心问题在真实的高并发服务中一个 RPC 框架的底线到底是什么以及如何在测试中衡量它。本文基于该文档结合仓库源码与配套文档完整还原 brpc 对自身及 UB、hulu-pbrpc、sofa-pbrpc、Apache Thrift、gRPC 六类框架的评测过程——从测试理念、环境配置到每一组 QPS/延时数据与结论。读完本文你将理解为什么能处理长尾是 RPC 性能测试的底线掌握如何设计一套可信的、可复现的 RPC 性能对比测试并知道如何在 brpc 中查看这些性能指标QPS、延时分位值、CDF 曲线。说明原文档明确标注以下测试于 2015 年完成不一定反映当前版本的最新状态brpc 在测试后又经历了 1200 多次改动文档中记录的测试时代码为 r31906。本文保留原文档的测试数据与结论同时结合当前仓库源码讲解其背后的实现原理。一、测试缘起为什么百万 QPS 的 echo 程序没有指导意义1.1 多核时代的性能悖论线程切换的代价在多核前提下性能和线程紧密相关。线程间的跳转对高频 IO 操作的性能有决定性作用一次跳转意味着至少 3~20 微秒的延时由于每个核心的 L1 cache 独立测试所用 CPU 的 L2 cache 也是独立的随之而来的是大量 cache miss——一些变量的读取、写入延时从纳秒级上升到几百倍至微秒级需要等待 CPU 把对应的 cacheline 同步过来。这带来一个出乎意料的结果当每次处理都很简短时一个多线程程序未必比单线程程序更快。前者可能在每次付出大的切换代价后只做了一点点正事而后者在不停地做正事。但单线程也有代价它工作良好的前提是正事都很快否则一旦某次变慢后续的所有正事都会被延迟。以 HTTP server 为代表的程序每次处理时间可预测、对下游无阻塞调用适合使用多个不相交的单线程模型可最大化 CPU 利用率并提供稳定的延时——这正是 threading_overview.md 中单线程 reactor模型的典型应用。而检索类服务要复杂得多大量后端服务需要被访问、广泛存在的长尾请求使每次处理时间无法确定、排序策略越来越复杂。若仍使用多个不相交的单线程一次难以预计的性能抖动或一个大请求就可能导致后续一堆请求被延迟。因此为了避免请求之间相互影响请求级的线程跳转是 brpc 必须付出的代价brpc 的做法是使线程跳转最优化——通过 bthreadM:N 线程库在请求级实现调度。1.2 为什么旧的测试方法不可信然而对服务的性能测试往往不能体现这一点测试中的处理往往极为简单如 echo、累加数字使得线程切换的影响空前巨大。通过控制多线程和单线程处理的比例可以把一个测试服务的 QPS 从 100 万到 500 万随意操纵同机——这严重损伤了性能测试结果的可信度。真实服务并不是在累加一个数字或 echo 一个字符串一个 QPS 几百万的 echo 程序没有指导意义。鉴于此在发起性能测试一年后2015 年底brpc 又经历了 1200 多次改动之后作者决定 review 所有测试并加强其中的线程因素以获得对真实场景有明确意义的结果。具体来说新测试需要满足三个要求请求不应等长要有长尾考察 RPC 能否让请求并发否则一个慢请求会影响大量后续请求要有多级 server 的场景server 内用 client 访问下游 server考察 server 和 client 的综合表现要有一个 client 访问多个 server 的场景考察负载均衡是否足够并发——真实场景中很少有一个 client 只访问一个 server。这套测试场景的设计思路对其他服务的性能测试同样有借鉴意义。二、被测对象一览六类 RPC 框架及其背景为保证对比公平文档为每个被测框架记录了当时的代码版本与关键配置。注意名称中的_mc后缀代表 multiple connection多连接/连接池模式。2.1 UB及 nova_pbrpc 变种UB 是百度在 2008 年开发的 RPC 框架曾在百度产品线广泛使用现已被 brpc 代替。其主要局限包括每个请求独占一个连接连接池大规模服务中每台机器需保持大量连接限制了使用场景只支持 nsheadmcpack 协议扩展性差增加新协议/新功能往往要调整大段代码缺乏调试和运维接口服务运行状态对用户基本是黑盒只能靠低效打日志追踪问题。UB 有多个变种测试以百度网盟团队广泛使用的nova_pbrpc为 UB 的代表测试时代码 r10500变种时间序列化说明ubrpc2010 年.idl 文件类似 .proto描述 schema有使用但不广泛nova_pbrpc2012 年protobuf 代替 mcpack协议为 nshead users protobufpublic_pbrpc2013 年初protobuf协议为 nshead meta protobuf用户数据序列化两次性能差早期的 UB 支持 CPOOL 和 XPOOL分别使用select和 leader-follower 模型后来提供 EPOLL基于epoll处理多路连接。由于产品线大都是用 EPOLL 模型测试配置也使用 EPOLL。UB 只支持连接池其结果用 ubrpc_mc 指代。2.2 hulu-pbrpc百度在 2013 年基于 saberkylin 变种和 protobuf 实现的 RPC 框架多线程实现上问题较多已被 brpc 代替。测试时代码为pbrpc_2-0-15-27959_PD_BL。hulu-pbrpc只支持单连接结果用 hulu-pbrpc 指代。2.3 brpcINF百度基础设施在 2014 年底开发至今的 RPC 产品支持百度内所有协议不限于 protobuf并第一次统一了百度主要分布式系统和业务线的 RPC 框架。测试时代码为 r31906。brpc 既支持单连接也支持连接池前者的结果用 baidu-rpc 指代后者用 baidu-rpc_mc 指代。2.4 sofa-pbrpc百度大搜团队在 2013 年基于 boost::asio 和 protobuf 实现的 RPC 框架。测试时使用 ps/opensource 下的版本较新且与 GitHub 定期同步代码为sofa-pbrpc_1-0-2_BRANCH。sofa-pbrpc只支持单连接结果用 sofa-pbrpc 指代。2.5 Apache Thriftthrift 由 Facebook 最早于 2007 年开发是序列化方法和 RPC 框架包含独特的序列化格式和 IDL支持很多编程语言开源后改名 Apache Thrift。测试时使用 apache thrift代码为thrift_0-9-1-400_PD_BL。其缺点是代码看似分层清晰client 和 server 选择很多但没有一个足够通用——每个 server 实现只能解决很小一块场景每个 client 都线程不安全。由于 thrift 没有线程安全的 client每个线程中都得建立一个 client、使用独立连接。在测试中 thrift 其实占了其他实现的便宜它的 client 不需要处理多线程问题。结果用 thrift_mc 指代。2.6 gRPCGoogle 开发的 RPC 框架使用 HTTP/2 和 protobuf 3.0测试时代码为release-0_11分支。gRPC 并不是 stubby定位更像是为了推广 HTTP/2 和 protobuf 3.0。结果用 grpc 指代。三、测试方法把能处理长尾作为 RPC 的底线3.1 底线RPC 必须能处理长尾如序言所解释性能数字有巨大的调整空间关键在于是什么底线要求。脱离底线测试中的表现就严重偏离真实环境。这个底线是RPC 必须能处理长尾。在百度的环境中哪个产品线、哪个系统没有长尾呢作为承载大部分服务的 RPC 框架自然得处理好长尾减少长尾对正常请求的影响。但在实现层面这个问题对设计的影响太大如果测试中没有长尾RPC 实现就可以假设每个请求都差不多快此时最优方法是多个线程独立处理请求。由于没有上下文切换和 cache 一致性同步程序性能会显著高于多线程协作。比如简单 echo 程序处理一个请求只需 200~300 纳秒单个线程可达 300~500 万吞吐而多线程协作即使在极其流畅的系统中也要付出 3~5 微秒的上下文切换代价和 1 微秒的 cache 同步代价一般单线程吞吐很难超过 10 万即使 24 核全部用满也只有 240 万不及一个线程。多线程付出这么大代价是为了隔离请求间的影响一个计算复杂或索性阻塞的过程不会影响其他请求1% 的长尾最终只会影响 1% 的性能而多个独立线程保证不了这点——一个请求进入一个线程就等于定了终生前面的请求慢了一下后面的也只能跟着慢1% 的长尾会影响远超 1% 的请求。换句话说乍看上去多线程模型慢了但在真实应用中反而会获得更好的综合性能。这正是 brpc 采用 bthreadM:N 线程库做请求级调度的根本原因相关线程模型的完整讨论见 threading_overview.md。3.2 为什么用延时而不是 QPS 衡量长尾干扰延时能精确体现长尾的干扰作用如果普通请求的延时没有被长尾请求干扰说明 RPC 成功地隔离了请求。而 QPS 无法体现这点——只要 CPU 都在忙即使一个正常请求进入了挤满长尾的队列而被严重延迟最终 QPS 也变化不大。因此所有涉及延时的测试都注入了 1% 的长尾请求人为制造慢请求长尾请求的延时不计入结果因为我们考察的是普通请求是否被长尾请求拖累。这正是这套测试方法论的精髓。四、测试环境与统一配置4.1 硬件环境性能测试使用的机器分三组环境配置说明单机 124 核开超线程E5-2620 2.00GHz64GB 内存Linux 2.6.32_1-15-0-0用于同机测试多机 115 台 8 台12 核未开超线程15 台为 E5-2420 1.90GHz64GB 内存千兆网卡无法开启多队列其余 8 台为 E5-2620 2.0GHz千兆网卡绑定多队列到前 8 个核长期测试机器较杂、跨多机房测试中延时在 1ms 以上的就是这批机器多机 230 台12 核未开超线程E5-2620 v3 2.40GHz96GB 内存Linux 2.6.32_1-17-0-0万兆网卡绑定多队列到前 8 个核临时借用的新机器都在广州机房延时很短测试中延时在几百微秒的就是这批机器所有曲线图均使用 brpc 开发的 dashboard 程序绘制去掉路径后可以看到和所有 brpc server 一样的内置服务。4.2 各 RPC 的测试配置如无特殊说明所有测试中的配置只是数量差异线程数、请求大小、client 个数等而不是模型差异确保用户看到的 QPS 和延时是同一个场景的不同维度而非无法统一的两个场景。所有 RPC server 都配置了24 个工作线程这些线程一般运行用户的处理逻辑。关于每种 RPC 的特殊说明UB配置 12 个 reactor 线程使用 EPOLL 模型连接池限制数配置为线程个数24。hulu-pbrpc额外配置 12 个 IO 线程处理 fd 读取、请求解析等。hulu 有个共享队列配置项默认不打开——其作用是把 fd 静态散列到多个线程中线程间不再争抢QPS 显著提高但会明显被长尾影响原因见测试方法。考虑到大部分使用者不会改配置测试中也不打开。thrift额外配置 12 个 IO 线程。client 不支持多线程每个线程使用独立 client连接也全部分开。sofa-pbrpc按 sofa 同学要求把io_service_pool_size配置为 24、work_thread_num配置为 1即 24 组线程池、每组 1 个 worker thread。与 hulu 不打开共享队列时类似该配置显著提高 QPS但同时使其失去处理长尾的能力。文档明确建议真实产品中不要用这个配置而应该用io_service_pool_size1, work_thread_num24。brpc尽管 brpc 的 client 运行在 bthread 中时会获得 10%~20% 的 QPS 提升和更低延时但测试中的 client 都统一运行在 pthread 中以保持对比公平。4.3 client 的发送方式同步多线程所有 RPC client 都以多个线程同步方式发送这种方法最接近于真实系统在考察 QPS 时也兼顾了延时因素。文档特别指出一种流行但不可取的方案client 不停地往连接中写数据看 server 表现。其弊端在于server 一下子能读出大量请求不同 RPC 的比拼变成了for 循环执行用户代码的比拼而不是分发请求的效率——真实系统中 server 很少能同时读到超过 4 个请求该方法完全放弃延时client 实际让 server 陷入了雪崩时才会进入的状态所有请求都因大量排队而超时。五、七组测试场景数据、图表与逐项分析以下测试按同机/跨机和单 client/多 client/多 server/多级 server两个维度组织共 7 组。为控制篇幅本文选取 3 张最具代表性的曲线图其余场景的完整图表均可在 docs/images 目录中找到qps_vs_multi_client.png、multi_client_latency_cdf.png、multi_server_latency_cdf.png等。5.1 同机单 client → 单 server不同请求大小下的 QPS本测试运行在单机 1上。图中的数值均为用户数据的字节数实际请求尺寸还要包括协议头一般会增加 40 字节左右X 轴是用户数据字节数Y 轴是对应 QPS。以_mc结尾的曲线代表 client 和 server 保持多个连接线程数个在本测试中会有更好的表现。分析brpc请求包小于 16KB 时单连接下的吞吐超过了多连接的 ubrpc_mc 和 thrift_mc随请求包变大内核对单个连接的写入速度成为瓶颈。而多连接下的 brpc 达到了测试中最高的2.3GB/s。注意虽然使用连接池的 brpc 在发送大包时吞吐更高但也会耗费更多 CPUUB 和 thrift 同样如此。下图中的单连接 brpc 已能提供 800 多兆吞吐足以打满万兆网卡而使用的 CPU 可能只有多连接下的 1/2写出过程是 wait-free 的真实系统中请优先使用单连接。thrift初期明显低于 brpc随包变大超过了单连接的 brpc。UB与 thrift 类似曲线但平均低 4~5 万 QPS在 32K 包时超过单连接的 brpc整个过程 QPS 几乎没变。gRPC初期几乎与 UB 平行但低 1 万左右超过 8K 后开始下降。hulu-pbrpc 和 sofa-pbrpc512 字节前高于 UB 和 gRPC之后急转直下、相继垫底——这是写不够并发的迹象。5.2 同机单 client → 单 server不同线程数下的 QPS本测试运行在单机 1 上X 轴是线程数Y 轴是对应 QPS。分析brpc随发送线程增加QPS 快速增加有很好的多线程扩展性。UB 和 thrift8 个线程下高于 brpc但超过 8 个线程后被 brpc 迅速超过thrift 继续平移UB 出现明显下降。gRPC、hulu-pbrpc、sofa-pbrpc几乎重合256 个线程时相比 1 个线程只有 1 倍提升多线程扩展性不佳。5.3 同机单 client → 单 server固定 QPS 下的延时 CDF本测试运行在单机 1 上。考虑到不同 RPC 的处理能力选择了一个较低、在不少系统中会达到的 QPS1 万。测试中有1% 的长尾请求耗时 5 毫秒长尾请求的延时不计入结果因为我们考察的是普通请求是否被及时处理了X 轴是延时微秒Y 轴是小于 X 轴延时的请求比例。关于 CDF 的判读方法越左越好延时小、越直越好没有长尾抬升分位值与 CDF 的完整定义参见 vars.md#统计和查看分位值。分析brpc平均延时短几乎没有被长尾影响。UB 和 thrift平均延时比 brpc 高 1 毫秒受长尾影响不大。hulu-pbrpc走向和 UB、thrift 类似但平均延时进一步增加 1 毫秒。gRPC初期不错到长尾区域后表现糟糕直接有一部分请求超时了反复测试都是这样像是有 bug。sofa-pbrpc30% 的普通请求图中未显示被长尾严重干扰。5.4 跨机多 client → 单 serverQPS本测试运行在多机 1上X 轴是 client 数Y 轴是对应 QPS。分析brpc随 client 增加server 的 QPS 快速增加有不错的 client 扩展性。sofa-pbrpcQPS 也快速增加但幅度不如 brpc从 16 个 client 到 32 个 client 时提升较小。hulu-pbrpcQPS 在增加但幅度进一步小于 sofa-pbrpc。UB增加 client 几乎不能增加 server 的 QPS。thrift平均 QPS 低于 UB增加 client 几乎不能增加 server 的 QPS。gRPC垫底增加 client 几乎不能增加 server 的 QPS。5.5 跨机多 client → 单 server固定 QPS 下的延时 CDF本测试运行在多机 1 上。负载均衡算法为 round-robin 或 RPC 默认提供的。由于有 32 个 client 且一些 RPC 的单 client 能力不佳为每个 client 仅设定2500 QPS——这是一个真实业务系统能达到的数字。测试中有1% 的长尾请求耗时 15 毫秒长尾请求的延时不计入结果。分析brpc平均延时短几乎没有被长尾影响。UB 和 thrift平均延时短受长尾影响小平均延时高于 brpc。sofa-pbrpc14% 的普通请求被长尾严重干扰。hulu-pbrpc15% 的普通请求被长尾严重干扰。gRPC已经完全失控非常糟糕。5.6 跨机多 client → 多 server固定 QPS 下的延时 CDF本测试运行在多机 2上20 台机器每台运行 4 个 client多线程同步访问 10 台 server。负载均衡算法为 round-robin 或 RPC 默认提供。由于 gRPC 访问多 server 较麻烦且有很大概率仍表现不佳此测试不包含 gRPC。测试中有1% 的长尾请求耗时 10 毫秒长尾请求延时不计入结果。分析brpc 和 UB平均延时短几乎没有被长尾影响。thrift平均延时显著高于 brpc 和 UB。sofa-pbrpc2.5% 的普通请求被长尾严重干扰。hulu-pbrpc22% 的普通请求被长尾严重干扰。5.7 跨机多 client → 多 server → 多 server固定 QPS 下的延时 CDF本测试运行在多机 2 上是唯一的多级 server 场景14 台机器每台运行 4 个 client多线程同步访问 8 台 server这些 server 还会同步访问另外 8 台 server。负载均衡算法为 round-robin 或 RPC 默认提供同样不包含 gRPC。测试中有1% 的长尾请求耗时 10 毫秒长尾请求延时不计入结果。分析brpc平均延时短几乎没有被长尾影响。UB平均延时短长尾区域略差于 brpc。thrift平均延时显著高于 brpc 和 UB。sofa-pbrpc17% 的普通请求被长尾严重干扰其中 2% 的请求延时极长。hulu-pbrpc基本消失在视野中已无法正常工作。六、测试结论汇总框架吞吐平均延时长尾处理关键短板brpc优秀单机最高 2.3GB/s优秀优秀无明显短板UB扩展性差线程/client 数几乎不能提升吞吐不错不错吞吐扩展性thrift单机尚可单机尚可多机明显高于 brpc/UB尚可多机延时、吞吐扩展性sofa-pbrpc小包尚可大包显著偏低受长尾影响很大差大包吞吐、长尾hulu-pbrpc单机与 sofa 类似多机表现极差差多机延时gRPC几乎所有测试垫底不佳差长尾区域有请求超时整体表现文档对 gRPC 的结论措辞谨慎它几乎在所有参与的测试中垫底可能它的定位是给 Google Cloud Platform 用户提供一个多语言、对网络友好的实现性能还不是要务。七、如何在 brpc 中复现与观测这些指标7.1 用 rpc_press 快速压测如果你要在自己的服务上复现类似的压测可以直接使用 brpc 自带的 rpc_press 工具它无需写代码即可压测各种 RPC server支持 baidu_std、hulu-pbrpc、sofa-pbrpc、public_pbrpc、nova_pbrpc、google_grpc 等协议。rpc_press 会动态加载 proto 文件、把 JSON 输入转为 pb 请求所有选项均来自命令行参数。例如./rpc_press -protoecho.proto -methodexample.EchoService.Echo \ -server0.0.0.0:8002 -input{message:hello} {message:world} -qps100常用参数包括-protocol默认 baidu_std、-connection_typesingle/pooled/short默认由协议自动选择、-lb_policyrr/random/la/p2c/c_murmurhash/c_md5、-timeout_ms默认 1000、-max_retry默认 3、-qps0 表示最大速度自适应、-duration0 表示持续发送直到 Ctrl-C、-dummy_port默认 8888。rpc_press 启动后默认在 8888 端口启动一个 dummy server可以在浏览器中观察其运行情况命令行中也会定期打印延时分布2016/01/30-16:19:01 sent:101 success:101 error:0 total_error:0 total_sent:28379 [Latency] avg 122 us 50% 122 us ... 99% 172 us 99.9% 199 us 99.99% 199 us max 199 us第一项avg是 10 秒内的平均延时最后一项max是最大延时其余以百分号结尾的为延时分位值即有左侧这么比例的请求延时小于右侧的值单位微秒。一般性能测试需要关注 99% 之后的长尾区域——这与本文的核心方法论一脉相承。7.2 用 /vars 与 CDF 曲线观测真实服务的延时brpc 的每个服务都会自动统计延时分布无需用户自己埋点可通过内置服务中的/vars页面查看/vars列出所有曝光的 bvar 计数器/vars/NAME查询单个也支持通配符用$代替?匹配单字符因为?是 URL 保留字符。命令行同样可访问$ curl brpc.baidu.com:8765/vars/bthread* bthread_creation_count : 125134 bthread_creation_latency : 3 bthread_creation_latency_99 : 7 bthread_creation_latency_cdf : click to view bthread_creation_qps : 100 bthread_num_workers : 24bvar::LatencyRecorder可统计任何代码的延时用法见 bvar_c.md记录后即可在/vars看到client_latency、client_latency_cdf等变量点击查看动态曲线。判断 CDF 曲线好坏的两个简单规则详见 vars.md#统计和查看分位值越平越好水平线意味着所有数值都相等没有任何等待、拥塞、停顿99% 与 100% 之间的面积越小越好99% 之后是长尾的聚集地对大部分系统的 SLA 有重要影响。一条缓慢上升且长尾区域面积不大的 CDF 便是不错的曲线。分位值能比平均值更准确刻画数值分布工业级应用的 SLA 一般在 99.97% 以上百度对二级系统的要求一级是 99.99% 以上一些系统即使平均值不错不佳的长尾区域也会明显拉低并打破 SLA——这正是本文所有延时测试都注入长尾请求的原因。7.3 测试配置背后的实现依据benchmark 文档中的几处配置与结论均可在仓库源码与配套文档中找到对应实现单连接 vs 连接池的取舍brpc 支持短连接、连接池、单连接三种连接方式。单连接下一个连接上可能同时有多个请求回复返回顺序和请求顺序不需要一致cpu 占用最低合并写出在大流量时减少 cpu 占用连接池则一个连接上最多只有一个请求。连接池大小由-max_connection_pool_size默认 100定义于 src/brpc/socket.cpp控制闲置连接由-idle_timeout_second默认 10 秒自动关闭。这解释了为何 brpc 单连接能在大包场景用更少 CPU 打满万兆网卡。wait-free 的发消息机制brpc 使用一种 wait-free MPSC 链表实现多线程向同一 fd 高效排队写数据详见 io.md#发消息这正是单连接 brpc 高吞吐、低 CPU 的底层原因。核心结构是 Socket——用 64 位 SocketId 指代 Socket 对象以方便多线程环境下使用 fd其Address是 wait-free 的。收消息的并发性brpc 使用一个或多个 EventDispatcherEDISP等待 fd 事件但 EDISP 不负责读取收到事件后启动 bthread 处理对应 fd 上的数据fd 内多条消息也会分别启动 bthread 并发处理见 InputMessenger。fd 间和 fd 内的消息都会获得并发正是 brpc 擅长处理大消息、在高负载下仍能及时处理不同来源消息、减少长尾的原因这也与 benchmark 中 brpc 长尾表现优秀的结果相互印证。八、结语这套测试方法论的价值benchmark 文档最有价值的产出并非brpc 赢了这个结论而是一套可迁移的 RPC 性能测试方法论以能处理长尾为底线设计测试——没有长尾的压测可以被随意操纵脱离真实场景用延时CDF/分位值而非 QPS 衡量长尾干扰——QPS 在 CPU 忙时无法反映排队恶化覆盖单机/跨机、单 client/多 client/多 server/多级 server 的场景矩阵——单一场景无法评估框架在真实拓扑中的综合表现统一除数量差异外的所有配置——保证对比的是模型差异而非配置差异。需要再次强调的是上述数据是 2015 年的测试快照brpc 代码 r31906不代表当前版本状态。如果你想评估当前版本的 brpc 或其他框架建议用上述方法在自己的硬件上重新跑一遍并用 brpc 自带的 rpc_press 与/vars页面观测真实场景下的吞吐与长尾表现。【免费下载链接】brpcbrpc is an Industrial-grade RPC framework using C Language, which is often used in high performance system such as Search, Storage, Machine learning, Advertisement, Recommendation etc. brpc means better RPC.项目地址: https://gitcode.com/GitHub_Trending/brpc/brpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表