ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

brpc benchmark_http 压测工具:用 brpc 高性能 HTTP 客户端压测 HTTP 服务极限

2026/9/13 13:54:47 拓冰建站 浏览量
brpc benchmark_http 压测工具:用 brpc 高性能 HTTP 客户端压测 HTTP 服务极限 brpc benchmark_http 压测工具用 brpc 高性能 HTTP 客户端压测 HTTP 服务极限【免费下载链接】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/brpcbenchmark_http 是 brpc 仓库 example/http_c 目录下自带的一个 HTTP 压测工具。它本质上就是一个基于 brpc HTTP client 的多线程压测程序通过 gflags 定义压测参数用 brpc::Channel 作为发压通道用 bvar::LatencyRecorder 实时统计 QPS 与延迟可以在命令行上替代 ab 完成 HTTP server 的极限性能测试。读完本文你将掌握 benchmark_http 的编译、启动、核心参数配置、发压原理与结果解读以及它相对于 ab 的优势与适用边界。为什么需要 benchmark_httpab 的瓶颈与 brpc 的答案ApacheBenchab功能较多但年代久远在压测超高吞吐的 HTTP server 时压测工具本身有时反而会成为瓶颈——当服务端 QPS 高到一定程度ab 自身的连接管理、线程模型与统计逻辑会先于被测服务打满导致测出的极限性能实际上是 ab 的极限而非服务器的极限。benchmark_http 的定位就是解决这个问题它基本上就是一个 brpc http client性能很高功能较少一般压测够用了。它继承了 brpc 在 I/O 线程模型、连接池管理、bthread 调度等方面的优化可以把更多 CPU 花在真正发起请求上从而压出被测 HTTP server 的真实上限。编译 benchmark_httpbenchmark_http 不是一个独立的工具而是随 brpc 的 http 示例一起编译的。按以下步骤操作先完成 brpc 的下载和编译支持 config_brpc.sh、CMake、Bazel 等多种构建方式进入example/http_c目录编译编译成功后即可看到benchmark_http可执行文件。以 Makefile 方式为例$ cd example/http_c $ make $ ls benchmark_http http_server http_client以 CMake 方式为例CMakeLists 中通过brpc_example_configure_target(benchmark_http)注册了该目标见 example/http_c/CMakeLists.txt$ cd example/http_c $ cmake -B build cmake --build build -j4 $ ls build/benchmark_http编译产物默认静态链接libbrpc.aMakefile 中STATIC_LINKINGS -lbrpc如需动态链接可先make clean再执行LINK_SO1 makeCMake 对应-DLINK_SOON。示例还默认开启了 CPU profiler 支持-DBRPC_ENABLE_CPU_PROFILER方便压测时定位客户端自身热点。提示example/http_c目录同时提供了http_server被测服务样例与http_client单次 HTTP 访问客户端benchmark_http 可与它们配合在本地快速搭建一套服务端 压测环境。核心参数总览benchmark_http 的所有压测参数都通过 gflags 定义在 example/http_c/benchmark_http.cpp可在启动时用-参数名值的方式传入。完整参数如下参数类型默认值说明-urlstring0.0.0.0:8010/HttpService/Echo被测服务器地址与路径格式为host:port/path-thread_numint3250发压线程数-use_bthreadboolfalse是否使用 bthread协程代替 pthread 发压-connection_typestring空连接方式single单连接、pooled连接池、short短连接为空则用协议默认方式-protocolstringhttp客户端协议对应 ChannelOptions.protocol-datastring空非空时以 POST 方式把该数据作为 body 发给服务器-load_balancerstring空负载均衡算法名用于多 server 地址场景-timeout_msint32100单次 RPC 超时时间毫秒-max_retryint323最大重试次数不含首次 RPC-dont_failboolfalse为 false 时只要有调用失败就触发 CHECK 致命错误并退出-dummy_portint32-1大于等于 0 时在该端口启动 dummy server用于暴露内置监控服务基本用法示例压测本机http_server样例的 Echo 服务默认监听 8010 端口$ ./benchmark_http -url0.0.0.0:8010/HttpService/Echo -thread_num50以 POST 方式压测并携带 body$ ./benchmark_http -url0.0.0.0:8010/HttpService/Echo -datahello world压测时直接观察 QPS 与延迟$ ./benchmark_http -url0.0.0.0:8010/HttpService/Echo -thread_num100 -timeout_ms1000工具启动后每秒打印一次实时统计见下节输出解读按 Ctrl-CSIGINT退出并输出退出日志。源码剖析benchmark_http 是如何发压的1. 构造 Channel一条线程安全、可共享的通信线main()中首先创建brpc::Channel与brpc::ChannelOptions把-protocol与-connection_type映射到 Channel 选项上再调用channel.Init(url, load_balancer, options)完成初始化benchmark_http.cpp#L79-L91brpc::Channel channel; brpc::ChannelOptions options; options.protocol FLAGS_protocol; // 默认 http options.connection_type FLAGS_connection_type; // single/pooled/short/空 if (channel.Init(FLAGS_url.c_str(), FLAGS_load_balancer.c_str(), options) ! 0) { LOG(ERROR) Fail to initialize channel; return -1; }关于三种连接方式的行为差异可参考 docs/cn/client.md#连接方式single单连接一个远端地址只建一条连接所有请求复用省去建连开销pooled连接池为单个远端维护连接池池容量上限由-max_connection_pool_size控制默认 100需要时若无空闲连接则新建归还时若池已满则直接关闭short短连接每次 RPC 前建连、结束后关闭有固定建连开销一般只用于偶尔发起的操作。-url为空时框架会按协议选择默认连接方式。注意-url同时承载了地址与路径channel.Init会对多地址配合-load_balancer做初始化而对单个地址brpc 会将其解析为可用的 endpoint。2. 创建发压线程pthread 还是 bthread根据-use_bthread标志工具选择用 pthread 还是 bthread 创建-thread_num个发送者线程所有线程共享同一个 Channelbenchmark_http.cpp#L93-L112if (!FLAGS_use_bthread) { pids.resize(FLAGS_thread_num); for (int i 0; i FLAGS_thread_num; i) pthread_create(pids[i], nullptr, sender, channel); } else { bids.resize(FLAGS_thread_num); for (int i 0; i FLAGS_thread_num; i) bthread_start_background(bids[i], nullptr, sender, channel); }sender是每个线程的执行体在!brpc::IsAskedToQuit()循环内不断构造brpc::Controller、设置超时与重试、填写http_request().uri()然后同步调用channel.CallMethod(...)done 为 nullptr 即同步等待响应或错误返回成功时把cntl.latency_us()写入全局的bvar::LatencyRecorderbenchmark_http.cpp#L41-L73。关键设计点同步调用 栈上 Controller因为同步等待返回cntl可直接放在栈上无需异步回调逻辑简单清晰失败节流当请求失败如无法连接服务器时线程会bthread_usleep(100000)100ms再继续避免失败场景下空转打满 CPU这也是源码注释明确说明的针对此压测工具的特殊休眠退出机制brpc::IsAskedToQuit()在收到 Ctrl-C 后返回 true主循环随之退出随后 join 所有线程并打印退出日志。3. 实时统计bvar::LatencyRecorder 与 QPS全局对象bvar::LatencyRecorder g_latency_recorder(client)benchmark_http.cpp#L39负责统计所有成功的请求。主线程每秒打印一次LOG(INFO) Sending FLAGS_protocol requests at qps g_latency_recorder.qps(1) latency g_latency_recorder.latency(1);qps(1)最近 1 秒的每秒请求数latency(1)最近 1 秒的平均延迟。由于 bvar 统计是增量式的长时间运行时只需每秒取一次快照即可得到近乎实时的吞吐与延迟曲线配合-dummy_port启动的 dummy server还可以通过 brpc 内置服务如/vars在线观察这些指标详见 docs/cn/builtin_service.md。4. 输出解读示例典型的运行输出形如INFO ... Sending http requests at qps283671 latency169 INFO ... Sending http requests at qps291054 latency166 INFO ... Sending http requests at qps289322 latency168 INFO ... benchmark_http is going to quit其中 qps 为最近 1 秒吞吐latency 为最近 1 秒平均延迟微秒。若出现error...与 CHECK 失败说明存在超时或连接失败当-dont_failfalse时此类失败会直接使进程以错误退出。参数调优实战建议1. 用 -thread_num 控制并发度-thread_num决定同时在途的请求数是压测并发度的直接来源。建议从较小值如 10逐步增大观察 QPS 是否继续上涨若 QPS 不再随线程数增长甚至下降说明已接近服务端或客户端瓶颈。注意工具使用同步阻塞式调用一个线程同一时刻只有一个在途请求因此线程数 ≈ 最大并发连接数连接池模式下还会受到-max_connection_pool_size约束。2. 用 -use_bthread 榨取客户端剩余性能bthread 是 brpc 的 M:N 协程实现参见 docs/cn/bthread.md。当单机核数有限、pthread 数量过大导致上下文切换成本高时-use_bthreadtrue可以在更少的系统线程上承载更多并发请求适合追求客户端侧极限吞吐的场景。3. 用 -connection_type 模拟不同连接模型压测长连接友好的服务如 HTTP/1.1 keep-alive用-connection_typesingle或-connection_typepooled想模拟短连接场景用-connection_typeshort但要意识到建连开销会显著拉低 QPS不指定留空则使用 http 协议默认方式适合快速上手。4. 用 -timeout_ms 与 -max_retry 控制压测语义-timeout_ms默认仅 100ms压测高延迟服务前务必调大如 1000~3000否则大量请求会因超时失败造成误判-max_retry默认 3表示失败后最多重试 3 次不含首次。压测中重试会放大服务器压力若只想测量原始请求成功率可设为 0。5. 用 -dummy_port 挂载内置监控$ ./benchmark_http -url0.0.0.0:8010/HttpService/Echo -dummy_port8088此时可访问http://localhost:8088/vars查看 client 侧 bvar 指标qps、延迟分位等也可以在压测过程中用 brpc 内置的 rpc_view、rpcz 等工具做更细致的观测参见 docs/cn/rpc_view.md。benchmark_http vs ab怎么选维度abbenchmark_http本质独立的 ApacheBench 程序基于 brpc 的 HTTP 客户端压测程序性能上限高并发下工具自身可能成为瓶颈复用 brpc 高性能 I/O 与连接池极限更高功能丰富度功能较多功能较少但一般压测够用参数模型-n/-c 等 ab 风格gflags 风格-thread_num/-connection_type 等统计输出汇总报告每秒实时打印 QPS 与平均延迟可挂内置监控适用建议做常规功能验证或低频压测可用 ab追求 HTTP server 极限性能测试、希望压测工具自身不成为瓶颈时优先使用 benchmark_http。更进一步把 benchmark_http 的思想搬进自己的服务benchmark_http 的源码结构本身就是如何用 brpc 写一个高并发 HTTP 客户端的极佳范例example/http_c/benchmark_http.cpp 中可直接借鉴的模式包括用 gflags 定义全部可调参数便于命令行/脚本化压测Channel 线程安全、全局共享线程只需各自持有 Controller同步调用时 Controller 放栈上配合IsAskedToQuit()实现优雅退出用bvar::LatencyRecorder做无锁化的高并发统计失败时 sleep 节流避免空转。如果你的压测场景需要更复杂的请求构造如带 header、Cookie、分块上传可直接扩展sender中对cntl.http_request()的填充逻辑需要多机分布式压测时还可参考 docs/cn/rpc_press.md 中 rpc_press 的多机压测思路。总结benchmark_http 是 brpc 仓库自带的 HTTP 压测工具本质是一个多线程的 brpc HTTP client用于替代 ab 测试 HTTP server 的极限性能编译入口在 example/http_c与 http_server/http_client 示例一同产出核心参数集中在 benchmark_http.cpp#L27-L37-url、-thread_num、-use_bthread、-connection_type、-protocol、-data、-timeout_ms、-max_retry、-dummy_port等发压原理为共享brpc::Channel 多线程/多协程同步调用 bvar::LatencyRecorder实时统计每秒打印 QPS 与平均延迟优势在于复用 brpc 的高性能客户端实现压测时工具自身不容易成为瓶颈代价是功能较少复杂压测场景如分布式多机压测可转向 rpc_press 等工具。【免费下载链接】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),仅供参考