【免费下载链接】brpc
brpc 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".
导读:本文基于 brpc 开源仓库官方文档 docs/cn/benchmark.md 展开,系统讲解 brpc 团队在 2015 年发起的一次跨框架基准性能测试——包括为什么 RPC 性能测试必须引入"长尾请求"、如何设计同机/跨机/多级 server 的测试拓扑、如何解读 QPS 与延时 CDF 曲线,以及 brpc 与 UB、hulu-pbrpc、sofa-pbrpc、Apache Thrift、gRPC 五个框架的对比结论。读完本文,你将掌握一套对真实生产场景有指导意义、可复用的 RPC 性能测试方法论,并理解 brpc 在吞吐、延时与长尾隔离上表现优异的底层原因(请求级线程跳转、wait-free 收发、bthread 调度等源码实现)。
关于本文数据的前提说明
本文所引用的测试结果来自 brpc 仓库官方文档 docs/cn/benchmark.md。该文档在开头明确注明:"following tests were done in 2015, which may not reflect latest status of the package"(以下测试于 2015 年完成,可能无法反映软件包的最新状态)。因此:
- 所有数字、曲线与排名结论都是2015 年底特定版本、特定机器、特定配置下的观测结果;
- 各参与框架当时的代码版本分别为:UB(nova_pbrpc)
r10500、hulu-pbrpcpbrpc_2-0-15-27959_PD_BL、brpcr31906、sofa-pbrpcsofa-pbrpc_1-0-2_BRANCH、thriftthrift_0-9-1-400_PD_BL、gRPC 对应release-0_11分支; - 时至今日,brpc 已历经大量迭代(仅测试发起后一年内就又有 1200 多次改动),这些框架的现状也已发生巨大变化。本文的价值在于其方法论,而不应被当作当下版本的横向性能排名来引用。
序言:为什么性能测试要谈"线程模型"
在进入具体测试数字之前,benchmark 文档花了大量篇幅解释一个根本性问题:多核时代,性能与线程是紧密绑定的。
线程跳转的代价:从纳秒到微秒
线程间的跳转对高频 IO 操作性能有决定性作用:一次跳转至少意味着3–20 微秒的延时。由于每个核心的 L1 cache 独立(当时的测试 CPU 上 L2 cache 也是独立的),跳转随之带来大量 cache miss——一些变量的读取、写入延时从纳秒级上升几百倍到微秒级,因为要等待 CPU 把对应的 cacheline 同步过来。
由此产生一个反直觉的结论:当每次处理都很简短时,多线程程序未必比单线程程序更快。前者可能在每次付出大的切换代价后只做了一点点"正事",而后者在不停地做"正事"。但单线程也有代价——它工作良好的前提是"正事"都很快,一旦某次变慢,后续所有"正事"都被延迟。
单线程模型适合什么,不适合什么
在处理时间普遍较短、可预测的程序中,(多个不相交的)单线程能最大化"做正事"的比例,延时表现也很稳定,各种 HTTP server 正是这样——这也是 threading_overview.md 中介绍的"单线程 reactor"模型(event-loop 派)被 HTTP server 广泛采用的原因:大部分 HTTP 请求的处理时间可预测,对下游的访问也没有阻塞代码,该模型能最大化 CPU 利用率并提供可接受的延时。
而 brpc 面对的检索类服务要复杂得多:
- 有大量后端服务需要访问;
- 广泛存在的长尾请求使每次处理的时间无法确定;
- 排序策略等业务逻辑越来越复杂。
在这种场景下,如果还使用(多个不相交的)单线程,一次难以预计的性能抖动,或一个大请求,可能导致后续一堆请求被延迟。这正是文档强调的核心:多线程付出上下文切换与 cache 同步的代价,目的是隔离请求间的影响——一个计算复杂或索性阻塞的过程不会影响到其他请求,1% 的长尾最终只影响到 1% 的性能。而多个独立的单线程保证不了这点:一个请求进入一个线程就等于"定了终生",前面的请求慢一下,后面的只能跟着慢,1% 的长尾会影响远超 1% 的请求。
请求级线程跳转是 brpc 的必然选择
为避免请求之间相互影响,请求级的线程跳转是 brpc 必须付出的代价,brpc 团队能做的是使线程跳转最优化。从源码层面看,brpc 的收消息路径由 event_dispatcher.h 中的 EventDispatcher(EDISP)与 input_messenger.h 中的 InputMessenger 协作完成:EDISP 收到事件后启动一个 bthread 处理对应 fd 上的数据,并把所在 pthread 让给新建的 bthread 以获得更好的 cache locality;fd 间和 fd 内的消息都会获得并发,发消息 一侧则通过 wait-free MPSC 链表实现多线程同时向一个 fd 写出数据,写出总能很快返回,调用线程可以更快地处理新任务。这些设计正是 brpc 在长尾场景下仍能隔离请求影响的底层基础。
既有性能测试的缺陷与改进方向
不过,对服务的性能测试还不能很好地体现上述设计价值:测试中的处理往往极为简单,使线程切换的影响空前巨大。通过控制多线程和单线程处理的比例,可以把一个测试服务的 QPS 从 100 万到 500 万操纵自如(同机)——这损伤了性能测试结果的可信度。真实服务并不是在累加一个数字或 echo 一个字符串,一个 QPS 几百万的 echo 程序没有指导意义。
鉴于此,在发起性能测试一年后(2015 年底)、brpc 又经历了 1200 多次改动后,团队决定 review 所有测试,加强其中的线程因素,以获得对真实场景有明确意义的结果。具体改进方向有三条:
- 请求不应等长,要有长尾:考察 RPC 能否让请求并发,否则一个慢请求会影响大量后续请求;
- 要有多级 server 的场景:server 内用 client 访问下游 server,考察 server 和 client 的综合表现;
- 要有一个 client 访问多个 server 的场景:考察负载均衡是否足够并发——真实场景中很少一个 client 只访问一个 server。
这套测试场景的设计思路对其他服务的性能测试同样具有借鉴意义。
测试目标:六个参与框架
UB(以 nova_pbrpc 为代表)
UB 是百度 2008 年开发的 RPC 框架,在百度产品线广泛使用,已被 brpc 代替。其特点与局限包括:
- 每个请求独占一个连接(连接池):在大规模服务中每台机器需要保持大量连接,限制了使用场景,百度的分布式系统没有用 UB;
- 只支持 nshead + mcpack 协议:扩展性差,增加新协议和新功能往往要调整大段代码,实践中大部分人"知难而退";
- 缺乏调试和运维接口:服务运行状态对用户基本是黑盒,只能靠低效地打日志追踪问题,排查效率低。
UB 有多个变种:
| 变种 | 时间 | 序列化方式 | 说明 |
|---|---|---|---|
| ubrpc | 2010 年 | .idl 文件(类似 .proto)描述 schema | 有被使用,但不广泛 |
| nova_pbrpc | 2012 年 | protobuf 代替 mcpack | 百度网盟团队开发,协议为 nshead + user's protobuf |
| public_pbrpc | 2013 年初 | protobuf 代替 mcpack | 协议与 nova_pbrpc 不同,大致为 nshead + meta protobuf;用户数据需序列化两次,性能很差,未推广 |
测试以在百度网盟团队广泛使用的 nova_pbrpc 为 UB 的代表(代码r10500)。早期的 UB 支持 CPOOL 和 XPOOL,分别使用 select 和 leader-follower 模型,后来提供 EPOLL(使用 epoll 处理多路连接);鉴于产品线大都是用 EPOLL 模型,测试配置使用 EPOLL。UB 只支持连接池这种连接方式,结果用"ubrpc_mc"指代(mc 代表 "multiple connection"),在文档语境下默认 ubrpc = UB。
hulu-pbrpc
百度 2013 年基于 saber(kylin 变种)和 protobuf 实现的 RPC 框架,多线程实现上有较多问题,已被 brpc 代替。测试时其代码为pbrpc_2-0-15-27959_PD_BL,只支持单连接,结果用"hulu-pbrpc"指代。
brpc
INF 2014 年底开发至今的 RPC 产品,支持百度内所有协议(不限于 protobuf),并第一次统一了百度主要分布式系统和业务线的 RPC 框架。测试时代码为r31906。brpc 既支持单连接也支持连接池,前者的结果用"baidu-rpc"指代,后者用"baidu-rpc_mc"指代。
brpc 的连接方式(短连接、连接池、单连接)在 client.md 中有完整说明,其中单连接指一个 client 与一个 server 只建立一个连接,供一个 fd 上的所有请求使用,是吞吐最高、也最省资源的连接方式;连接池则维持多个连接。具体到发送路径,socket.cpp 中的 wait-free MPSC 写出实现,使单连接在写出时也能高效并发。
sofa-pbrpc
百度大搜团队 2013 年基于 boost::asio 和 protobuf 实现的 RPC 框架。有多个版本,经咨询相关同学确认 ps/opensource 下的和 GitHub 上的较新且会定期同步,故测试使用 ps/opensource 下的版本,代码为sofa-pbrpc_1-0-2_BRANCH。只支持单连接,结果用"sofa-pbrpc"指代。
Apache Thrift
thrift 由 Facebook 最早在 2007 年开发,是序列化方法和 RPC 框架,包含独特的序列化格式和 IDL,支持很多编程语言。开源后改名 Apache Thrift,Facebook 自己有 fbthrift 分支,测试使用的是 apache thrift,代码为thrift_0-9-1-400_PD_BL。
文档对其缺点总结为:代码看似分层清晰,client 和 server 选择很多,但没有一个足够通用——每个 server 实现只能解决很小一块场景,每个 client 都线程不安全,实际使用很麻烦。由于 thrift 没有线程安全的 client,每个线程都得建立独立 client、使用独立连接。文档特别指出:在测试中 thrift 其实是占了其他实现的便宜——它的 client 不需要处理多线程问题。结果用"thrift_mc"指代。
gRPC
Google 开发的 RPC 框架,使用 HTTP/2 和 protobuf 3.0,测试时对应其release-0_11分支。文档指出 gRPC 并不是 stubby,定位更像是为了推广 HTTP/2 和 protobuf 3.0,但鉴于很多人对其表现感兴趣,团队也(很麻烦地)将其加入测试。结果用"grpc"指代。
测试方法:RPC 的底线是必须能处理长尾
如序言所解释的,性能数字有巨大的调整空间。关键在于:对 RPC 的底线要求是什么?脱离这个底线,测试表现就严重偏离真实环境。文档给出的底线是:
RPC 必须能处理长尾。
在百度的环境中,每个产品线、每个系统都有长尾,作为承载大部分服务的 RPC 框架自然得处理好长尾、减少长尾对正常请求的影响。但在实现层面,这个问题对设计的影响太大:
- 如果测试中没有长尾,RPC 实现就可以假设每个请求都差不多快,此时最优方法是用多个线程独立地处理请求。由于没有上下文切换和 cache 一致性同步,程序性能会显著高于多个线程协作时。
- 比如简单的 echo 程序,处理一个请求只需 200–300 纳秒,单个线程可以达到 300–500 万的吞吐;但如果多个线程协作,即使在极其流畅的系统中也要付出 3–5 微秒的上下文切换代价和 1 微秒的 cache 同步代价,还没考虑其他互斥逻辑——一般来说单个线程的吞吐很难超过 10 万,即使 24 核全部用满,吞吐也只有 240 万,不及一个线程。
这正是 threading_overview.md 所描述的取舍:多线程 reactor 因 cache 一致性的限制无法获得线性于核心数的性能,粗糙的多线程 reactor 实现跑在 24 核上甚至没有精致的单线程 reactor 跑在 1 个核上快;但多线程模型通过请求级隔离,让 1% 的长尾只影响 1% 的性能。乍看多线程"慢"了,在真实应用中反而会获得更好的综合性能。
如何度量长尾干扰:延时 CDF 而非 QPS
延时能精确体现长尾的干扰作用:如果普通请求的延时没有被长尾请求干扰,就说明 RPC 成功隔离了请求。而 QPS 无法体现这点——只要 CPU 都在忙,即使一个正常请求进入了挤满长尾的队列而被严重延迟,最终 QPS 也变化不大。
为测量长尾的干扰作用,所有涉及延时的测试都增加了1% 的长尾请求(长尾请求耗时毫秒级,且其延时不计入结果,因为考察的是普通请求是否被及时处理)。延时的统计与查看方式详见 vars.md:x% 分位值(percentile)指把一段时间内的 N 个统计值排序后第 N*x% 位的值;分位值可绘制为 CDF(累积分布函数)曲线——横轴是"数值 ≤ y 的比例",纵轴是对应分位值,中位数密度高,边上长尾很扁,所以系统测量普遍选择 CDF 而非 PDF;一条缓慢上升且长尾区域面积不大的 CDF 便是不错的曲线。工业级应用的 SLA 一般在 99.97% 以上,分位值能帮助分析长尾区域——这正是本文各延时图"越左越好、越直越好"的评判依据。
测试环境与配置
机器环境
性能测试使用三类机器:
| 机器组 | 配置 |
|---|---|
| 单机1 | CPU 开超线程 24 核,E5-2620 @ 2.00GHz;64GB 内存;OS linux 2.6.32_1-15-0-0 |
| 多机1(15台+8台) | CPU 均未开超线程 12 核;其中 15 台为 E5-2420 @ 1.90GHz、64GB 内存、千兆网卡(无法开启多队列);其余 8 台为 E5-2620 2.0GHz、千兆网卡、绑定多队列到前 8 个核。长期测试机器较杂,跨多个机房,测试中延时在 1ms 以上的就是这批机器 |
| 多机2(30台) | CPU 未开超线程 12 核,E5-2620 v3 @ 2.40GHz;96GB 内存;OS linux 2.6.32_1-17-0-0;万兆网卡,绑定多队列到前 8 个核。临时借用的新机器,配置非常好,都在广州机房,延时非常短,测试中延时在几百微秒的就是这批机器 |
下面所有的曲线图均使用 brpc 开发的 dashboard 程序绘制,去掉路径后可以看到和所有 brpc server 一样的内置服务——即 /status、/vars、/connections、/flags、/rpcz、cpu profiler、heap profiler、contention profiler 等,这也是观测 rpc_press 压力状态的标准入口(见后文"如何复现与观测")。
统一配置
如无特殊说明,所有测试中的配置只是数量差异(线程数、请求大小、client 个数等),而不是模型差异,确保用户看到的 QPS 和延时是同一个场景的不同维度,而非无法统一的两个场景。
所有 RPC server 都配置了24 个工作线程(一般运行用户的处理逻辑)。关于每种 RPC 的特殊说明:
- UB:配置 12 个 reactor 线程,使用 EPOLL 模型;连接池限制数配置为线程个数(24)。
- hulu-pbrpc:额外配置 12 个 IO 线程,处理 fd 读取、请求解析等任务。hulu 有个"共享队列"配置项,默认不打开,作用是把 fd 静态散列到多个线程,由于线程间不再争抢,QPS 会显著提高,但会明显被长尾影响(原因见上文"测试方法")。考虑到大部分使用者不会去改配置,测试也选择不打开。
- thrift:额外配置 12 个 IO 线程处理 fd 读取、请求解析;client 不支持多线程,每个线程使用独立 client、独立连接。
- sofa-pbrpc:按 sofa 团队要求,
io_service_pool_size配置为 24、work_thread_num配置为 1——即使用独立的 24 组线程池,每组 1 个 worker thread。和 hulu 不打开"共享队列"时类似,这个配置显著提高 QPS,但使其失去处理长尾的能力。文档明确建议:真实产品中不要用这个配置,而应该用io_service_pool_size=1, work_thread_num=24。 - brpc:尽管 brpc 的 client 运行在 bthread 中时会获得 10%~20% 的 QPS 提升和更低的延时,但测试中的 client 都运行在统一的 pthread 中——这是为了公平对比,也说明 brpc 在未启用 bthread 调度时仍有出色表现。bthread 是 brpc 使用的 M:N 线程库,关键技术在 bthread.md 中有介绍:work stealing 调度让 bthread 更快地被调度到更多核心上,butex 让 bthread 和 pthread 可以相互等待和唤醒。
压测客户端的发送方式
所有的 RPC client 都以多个线程同步发送方式压测,这最接近真实系统情况,在考察 QPS 时也兼顾了延时因素。
文档同时批判了一种流行方案:client 不停地往连接中写数据看 server 表现。其弊端在于:server 一下子能读出大量请求,不同 RPC 的比拼变成了"for 循环执行用户代码"的比拼,而不是分发请求的效率——真实系统中 server 很少能同时读到超过 4 个请求;而且该方法完全放弃延时,client 实际上是让 server 陷入雪崩时才会进入的状态(所有请求都因大量排队而超时)。
六组测试场景与结果分析
场景一:同机单 client → 单 server,不同请求大小下的 QPS(越高越好)
运行在单机1 上。图中的数值均为用户数据的字节数,实际请求尺寸还要包括协议头,一般增加约 40 字节。以_mc结尾的曲线代表 client 和 server 保持多个连接(线程数个)。
分析:
- brpc:请求包小于 16KB 时,单连接下的吞吐超过了多连接的 ubrp_mc 和 thrift_mc;随着请求包变大,内核对单个连接的写入速度成为瓶颈;而多连接下的 brpc 达到测试中最高的2.3GB/s。注意:使用连接池的 brpc 发送大包时吞吐更高,但也会耗费更多 CPU(UB 和 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-pbrpc:512 字节前高于 UB 和 gRPC,之后急转直下、相继垫底——这个趋势是写不够并发的迹象。
场景二:同机单 client → 单 server,不同线程数下的 QPS(越高越好)
运行在单机1 上。
分析:
- brpc:随着发送线程增加,QPS 快速增加,多线程扩展性很好。
- UB 和 thrift:8 个线程下高于 brpc,但超过 8 个线程后被 brpc 迅速超过;thrift 继续"平移",UB 出现明显下降。
- gRPC、hulu-pbrpc、sofa-pbrpc:几乎重合,256 个线程时相比 1 个线程只有 1 倍提升,多线程扩展性不佳。
场景三:同机单 client → 单 server,固定 QPS 下的延时 CDF(越左越好、越直越好)
运行在单机1 上。考虑到不同 RPC 的处理能力,选择了一个较低、在不少系统中会达到的 QPS:1 万。测试中有 1% 的长尾请求耗时 5 毫秒,长尾请求的延时不计入结果。
分析:
- brpc:平均延时短,几乎没有被长尾影响。
- UB 和 thrift:平均延时比 brpc 高 1 毫秒,受长尾影响不大。
- hulu-pbrpc:走向与 UB、thrift 类似,但平均延时进一步增加 1 毫秒。
- gRPC:初期不错,到长尾区域后表现糟糕,直接有一部分请求超时(反复测试都是这样,像是有 bug)。
- sofa-pbrpc:30% 的普通请求(上图未显示)被长尾严重干扰。
场景四:跨机多 client → 单 server 的 QPS(越高越好)
运行在多机1 上。
分析:
- brpc:随着 client 增加,server 的 QPS 快速增加,client 扩展性不错。
- sofa-pbrpc:随着 client 增加 QPS 也快速增加,但幅度不如 brpc;从 16 个 client 到 32 个 client 时提升较小。
- hulu-pbrpc:QPS 在增加,但幅度进一步小于 sofa-pbrpc。
- UB:增加 client 几乎不能增加 server 的 QPS。
- thrift:平均 QPS 低于 UB,增加 client 几乎不能增加 server 的 QPS。
- gRPC:垫底,增加 client 几乎不能增加 server 的 QPS。
场景五:跨机多 client → 单 server,固定 QPS 下的延时 CDF(越左越好、越直越好)
运行在多机1 上。负载均衡算法为 round-robin 或 RPC 默认提供的。由于有 32 个 client 且一些 RPC 的单 client 能力不佳,为每个 client 仅设定2500 QPS——一个真实业务系统能达到的数字。测试中有 1% 的长尾请求耗时 15 毫秒,长尾请求的延时不计入结果。
分析:
- brpc:平均延时短,几乎没有被长尾影响。
- UB 和 thrift:平均延时短,受长尾影响小,但平均延时高于 brpc。
- sofa-pbrpc:14% 的普通请求被长尾严重干扰。
- hulu-pbrpc:15% 的普通请求被长尾严重干扰。
- gRPC:已经完全失控,非常糟糕。
场景六:跨机多 client → 多 server → 多 server,固定 QPS 下的延时 CDF(越左越好、越直越好)
本场景实为两级 server 的级联访问。运行在多机2 上:20 台每台运行 4 个 client,多线程同步访问 10 台 server。负载均衡算法为 round-robin 或 RPC 默认提供的。由于 gRPC 访问多 server 较麻烦且很大概率仍表现不佳,此测试不含 gRPC。
分析:
- brpc 和 UB:平均延时短,几乎没有被长尾影响。
- thrift:平均延时显著高于 brpc 和 UB。
- sofa-pbrpc:2.5% 的普通请求被长尾严重干扰。
- hulu-pbrpc:22% 的普通请求被长尾严重干扰。
紧接着的三级级联场景(多 client → 多 server → 多 server)运行在多机2 上:14 台每台运行 4 个 client,多线程同步访问 8 台 server,这些 server 还会同步访问另外 8 台 server,此场景同样不含 gRPC。
分析:
- brpc:平均延时短,几乎没有被长尾影响。
- UB:平均延时短,长尾区域略差于 brpc。
- thrift:平均延时显著高于 brpc 和 UB。
- sofa-pbrpc:17% 的普通请求被长尾严重干扰,其中 2% 的请求延时极长。
- hulu-pbrpc:基本消失在视野中,已无法正常工作。
结论汇总
| 框架 | 吞吐 | 平均延时 | 长尾处理 | 扩展性 |
|---|---|---|---|---|
| brpc | 优秀(多连接下最高 2.3GB/s) | 优秀 | 优秀,几乎不受长尾影响 | 线程数与 client 数扩展性均好 |
| UB | 扩展性较差,提高线程数和 client 数几乎不能提升吞吐 | 不错 | 不错 | 差 |
| thrift | 单机尚可,多机一般 | 单机尚可,多机明显高于 brpc 和 UB | 一般 | 差 |
| sofa-pbrpc | 小包尚可,大包显著低于其他 | 受长尾影响很大 | 差(14%~30% 请求被干扰) | 尚可 |
| hulu-pbrpc | 单机与 sofa-pbrpc 类似 | 多机表现极差 | 差(15%~22% 请求被干扰) | 一般 |
| gRPC | 几乎在所有参与的测试中垫底 | — | 差(甚至超时、失控) | 差 |
文档对 gRPC 的结论是:几乎在所有参与的测试中垫底,其定位可能是给 Google Cloud Platform 的用户提供一个多语言、对网络友好的实现,性能还不是要务。
注意:以上均为 2015 年测试结论,且部分框架已停止维护(UB、hulu-pbrpc、sofa-pbrpc 已被 brpc 代替),gRPC 与 thrift 后续版本亦变化巨大,切勿将上表作为当下跨框架性能排名引用;其真正可复用的是"长尾优先 + 多级拓扑 + CDF 度量"的测试方法论。
如何复现与观测:rpc_press 实战
benchmark 文档给出了测试方法论的框架,若要在自己的服务上复现同类测试,可借助仓库自带的压测工具rpc_press(位于 tools/rpc_press),其完整用法见 docs/cn/rpc_press.md。要点如下:
获取工具:先按 Getting Started 编译好 brpc,再编译 tools/rpc_press。rpc_press 会动态加载 proto 文件,无需把 proto 编译为 C++ 源文件;它会加载 json 格式的输入文件、转为 pb 请求发向 server,收到 pb 回复后按需转为 json 写入指定文件。所有选项均来自命令行参数,而非配置文件。
必需参数:
-proto:指定相关的 proto 文件名;-method:指定方法名,形式必须是package.service.method;-server:当-lb_policy为空时是服务器的ip:port;当-lb_policy不为空时是集群地址(如bns://node-name、file://server_list等,具体见命名服务);-input:指定 json 请求或包含 json 请求的文件。
可选参数:
-inc:包含被 import 的 proto 文件的路径,多个路径用分号(;)分隔;-lb_policy:负载均衡算法,默认为空,可选项为rr random la c_murmurhash c_md5,具体见负载均衡;-timeout_ms:超时(毫秒),默认 1000;-max_retry:最大重试次数,默认 3,一般无需修改,重试行为见这里;-protocol:连接 server 使用的协议,默认为 baidu_std,可选项见协议;-connection_type:连接方式,可选项为single pooled short,见连接方式,默认根据协议自动选择;-output:非空时 response 转为 json 写入该文件,默认空;-duration:大于 0 表示发送这么多秒压力后退出,否则一直发直到 Ctrl-C,默认 0;-qps:大于 0 表示以此压力发送,否则以最大速度(自适应)发送,默认 100;-dummy_port:修改 dummy_server 端口,默认 8888。
常用命令示例(对应本文"多 client 多线程同步发送"的压测形态):
# 向 0.0.0.0:8002 用 baidu_std 以固定 100 QPS 持续发送 ./input.json 中的请求 ./rpc_press -proto=echo.proto -method=example.EchoService.Echo \ -server=0.0.0.0:8002 -input=./input.json -qps=100 # 以 round-robin 分流向 bns://node-name 代表的所有下游发送,固定 100 QPS ./rpc_press -proto=echo.proto -method=example.EchoService.Echo \ -server=bns://node-name -lb_policy=rr \ -input='{"message":"hello"} {"message":"world"}' -qps=100 # 以最大压力持续发送 10 秒 ./rpc_press -proto=echo.proto -method=example.EchoService.Echo \ -server=0.0.0.0:8002 -input='{"message":"hello"} {"message":"world"}' \ -qps=0 -duration=10观测方法:rpc_press 启动后默认在 8888 端口启动一个 dummy server,浏览器打开即可看到和所有 brpc server 一致的内置服务页面;切换到 vars 页面并在 Search 框中输入rpc_press可以看到当前压力的延时分布情况。若无法打开浏览器,命令行也会定期打印sent / success / error信息以及[Latency]分位值列表(avg、50%、70%、90%、95%、97%、99%、99.9%、99.99%、max,单位微秒)——一般性能测试需要关注 99% 之后的长尾区域,这与本文所有延时 CDF 测试"考察普通请求是否被长尾影响"的视角完全一致。
延伸阅读
- docs/cn/threading_overview.md:常见线程模型(连接独占线程、单线程 reactor、N:1 线程库、多线程 reactor、M:N 线程库)及其多核扩展性与异步编程问题——本文序言部分的理论基础;
- docs/cn/io.md:brpc 收消息、发消息与 Socket 的完整实现,The full picture 给出全链路图,发消息 讲解 wait-free 写出——本文"单连接也能高吞吐"的源码依据;
- docs/cn/bthread.md:brpc 的 M:N 线程库,work stealing 调度与 butex——理解 brpc 请求级调度与长尾隔离的关键;
- docs/cn/client.md:命名服务、负载均衡(rr、random、la、c_murmurhash、c_md5 等)与连接方式;
- docs/cn/vars.md:分位值(percentile)与 CDF 的统计、查看方法——解读本文所有延时曲线的方法依据;
- docs/cn/rpc_press.md:rpc_press 压测工具完整参数与使用示例;
- docs/cn/builtin_service.md:dashboard 曲线的来源,即每个 brpc server 自带的 /status、/vars、/rpcz 等内置服务;
- 核心实现源码:src/brpc/event_dispatcher.h、src/brpc/input_messenger.h、src/brpc/socket.h、src/brpc/socket.cpp。
【免费下载链接】brpc
brpc 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".
相关推荐
brpc 性能基准测试深度解读:基于长尾场景的多框架对比与测试方法论
brpc 性能基准测试深度解读:基于长尾场景的多框架对比与测试方法论 本文以 brpc 仓库中的 docs/cn/benchmark.md https://li
AI Agent人工智能大模型AI 应用工具调用本地部署MCP ClientsAgent 记忆GUI 自动化ComfyUI 视频生成实战:用 WanVideo 工作流把一张照片变成 81 帧视频
ComfyUI 视频生成实战:用 WanVideo 工作流把一张照片变成 81 帧视频 在消费级显卡上跑通 ComfyUI WanVideoWrapper 的图
人工智能大模型媒体生成终极指南:gRPC性能基准测试与主流RPC框架全面对比分析
终极指南:gRPC性能基准测试与主流RPC框架全面对比分析 gRPC作为现代云原生应用的远程过程调用(RPC)框架,以其跨语言支持、高效二进制协议和强大的生态系
后端RPC框架微服务通信
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考