news 2026/9/22 9:49:53

brpc 内置指标查询指南:通过 /vars 监控 bvar 计数器与延迟分位数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
brpc 内置指标查询指南:通过 /vars 监控 bvar 计数器与延迟分位数
  • RPC框架
  • 后端
  • 微服务
  • 网络
  • 通信

【免费下载链接】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".

项目地址:https://gitcode.com/gh_mirrors/brpc6/brpc
点击查看免费下载

brpc 默认集成 bvar 计数器库,所有进程内暴露(expose)的 bvar 都可以通过内置服务/vars以 HTTP 方式查询。本文以官方文档 docs/en/vars.md 为主线,结合 src/bvar 与 src/brpc/builtin/vars_service.cpp 的源码实现,讲解如何用精确名、通配符检索 bvar、查看历史趋势曲线,以及如何计算和解读 CDF / 百分位延迟曲线,最终帮助你用这些指标定位性能长尾、保障 SLA。

bvar 是什么:为什么值得监控

bvar 是一套面向多线程应用的高性能计数器库,用于方便地记录和查看各类统计信息。其核心设计是通过**线程局部存储(TLS)**降低缓存一致性开销(cache bouncing):每个线程只写自己私有的数据区,不参与全局原子竞争,读取时再把所有线程的数据合并。因此在高度竞争的场景下,bvar 的写入开销远低于传统原子操作,也明显快于百度内部的旧版统计库 UbMonitor。

这一设计也决定了它的适用边界:bvar 把写入时的竞争转移到了读取端——读取需要合并所有线程写下的数据,比普通读取慢得多。所以文档明确指出:如果某个计数器的读写都很频繁,或者需要基于最新值立刻做决策,就不应使用 bvar。它最适合低频率的日志输出、监控展示这类"写多读少"的场景。

brpc 自身大量使用 bvar 暴露内部状态,例如:

bthread_creation_count : 125134 bthread_creation_latency : 3 bthread_creation_latency_50 : 3 bthread_creation_latency_90 : 5 bthread_creation_latency_99 : 7 bthread_creation_latency_999 : 12 bthread_creation_latency_9999 : 12 bthread_creation_latency_cdf : "click to view" bthread_creation_latency_percentiles : "[3,5,7,12]" bthread_creation_max_latency : 7 bthread_creation_qps : 100 bthread_group_status : "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " bthread_num_workers : 24 bthread_worker_usage : 1.01056

此外 bvar 还默认提供以process_/system_为前缀的进程级、系统级指标(见 docs/en/bvar.md):

process_context_switches_involuntary_second : 14 process_cpu_usage : 0.428 process_cpu_usage_user : 0.286 process_disk_write_bytes_second : 260902 process_memory_resident : 392744960 system_core_count : 12 system_loadavg_1m : 0.000

如果你正在为应用寻找一个采集与展示指标的方案,bvar 值得优先考虑——brpc 服务天然将其暴露,无需额外埋点即可看到大量内部状态。

/vars 查询方法:精确名、多名称与通配符

只要服务是 brpc server(内置服务默认开启),就可以通过以下 URL 查询 bvar:

查询方式示例说明
列出全部/vars列出所有已暴露的 bvar
按名称查询/vars/rpc_socket_count列出名为rpc_socket_count的 bvar
按多个名称查询/vars/pid;process_cpu_usage;rpc_controller_count同时列出多个名称(用;,或空格分隔)
通配符匹配/vars/rpc_server*_count;iobuf_blo$k_*按通配符模式匹配一组 bvar

关于通配符有一个易错点:$匹配单个字符,而?是 URL 中的保留字符不能直接使用。这一点在源码中也有印证——src/brpc/builtin/vars_service.cpp 在构造bvar::DumpOptions时将question_mark显式设置为'$'white_wildcards则取自 HTTP 请求的未解析路径(unresolved_path),随后调用bvar::Variable::dump_exposed()完成过滤输出。

通配符的过滤行为由 src/bvar/variable.cpp 中的bvar_dump_include/bvar_dump_exclude相关机制同一套代码支撑(DumpOptions同时支持白名单与黑名单通配符),所以 URL 查询与文件 dump 的匹配语义是一致的。

/vars页面左上角还提供了一个搜索框:输入名称片段即可实时定位 bvar,多个模式之间用,:或空格分隔,搜索请求会实时回发到服务端并刷新列表(对应vars_service.cpptoURL()/search()这段前端逻辑)。你可以把带通配符的 URL 直接复制粘贴分享给他人,对方会看到与你相同的 bvar 列表(数值可能随时间变化)。

在终端用 curl 查询 /vars

/vars同样支持命令行访问。浏览器请求时会返回 HTML 页面(服务端通过UseHTML()判断并设置text/html内容类型),而 curl 等终端工具默认得到纯文本输出(text/plain),格式为每行一条name : value

$ curl brpc.baidu.com:8765/vars/bthread* bthread_creation_count : 125134 bthread_creation_latency : 3 bthread_creation_latency_50 : 3 bthread_creation_latency_90 : 5 bthread_creation_latency_99 : 7 bthread_creation_latency_999 : 12 bthread_creation_latency_9999 : 12 bthread_creation_latency_cdf : "click to view" bthread_creation_latency_percentiles : "[3,5,7,12]" bthread_creation_max_latency : 7 bthread_creation_qps : 100 bthread_group_status : "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " bthread_num_workers : 24 bthread_worker_usage : 1.01056

注意上述示例中的brpc.baidu.com:8765是官方演示服务地址,实际使用时应替换为你自己的 brpc 服务地址与端口(例如127.0.0.1:8000/vars/...)。从源码看,/vars返回时还会启用 gzip 压缩(cntl->set_response_compress_type(COMPRESS_TYPE_GZIP)),所以即便 bvar 数量很大,传输开销也可控。

除了网页与 curl,还可以给 URL 追加?series参数:VarsService::default_method()会检测到series查询参数后调用bvar::Variable::describe_series_exposed(),以application/json返回该 bvar 的时序采样数据,这正是前端绘图所依赖的数据接口(src/brpc/builtin/vars_service.cpp)。

查看历史趋势:60 秒、60 分钟、24 小时与 30 天

大多数数值型 bvar 都是可点击的。点击后页面会展示该指标的历史趋势曲线,每个可点击的 bvar 会记录最近60 秒、60 分钟、24 小时、30 天四个时间尺度的采样值,合计174个数值。

这 174 个数值并非估算,而是源码中实实在在的数据布局。在 src/bvar/detail/series.h 中,序列数据被保存在定长数组里:

T _array[60 + 60 + 24 + 30];

其中前 60 格存秒级样本,接着 60 格存分钟级、24 格存小时级、30 格存天级。正因为内存占用是固定的,文档才给出"1000 个可点击的 bvar 大约占用 1M 内存"的估算(每个 bvar 约 1KB,174 × 若干字节/样本)。

这些序列由采样器线程周期驱动:bvar::detail::Samplertake_sample()会被一个专用线程每秒调用一次(见 src/bvar/detail/sampler.h),ReducerSampler会把每秒的快照压入有界队列BoundedQueue,后续按窗口尺寸求差值或求和即可得到任意时间窗的统计值。这也解释了为什么Window<>类指标在极端情况下会有一秒的延迟——它们的数据来自每秒一次的采样。

计算与查看百分位数(Percentile)

百分位数的含义

x-ile(x 百分位)指一组有序数值中位于N × x%位置的值。例如时间窗口内有 1000 个延迟样本,升序排列后:

  • 第 500 个值(1000 × 50%)即 50-ile,也就是中位数
  • 第 990 个值(1000 × 99%)是 99-ile;
  • 第 999 个值(1000 × 99.9%)是 99.9-ile。

相比平均值,百分位数能揭示延迟的真实分布,对分析系统行为更准确。工业级服务通常对 SLA 有硬性要求——例如百度内部二级服务要求不低于 99.97%,一级服务不低于 99.99%——即使平均延迟很好,糟糕的长尾区域仍可能击穿 SLA。百分位数正是分析长尾区域最直接的武器。

CDF 曲线:看分布形状

百分位数可以绘制成 CDF(累积分布函数)曲线或"百分位随时间变化"曲线。

CDF 图的 X 轴是比例(排序位置 / 总数),Y 轴是对应的百分位值。例如 X=50% 对应的 Y 值就是 50-ile。如果系统要求"99.9% 的请求要在 Y 毫秒内处理完",就应该检查 X=99.9% 处的 Y 值。

为什么叫 CDF?因为任取一个 Y=y,其对应的 X 表示"值 ≤ y 的比例"。由于样本是(近似均匀)随机采样,这个比例可以看作"值 ≤ y 的概率",即 P(values ≤ y),这正是 CDF 的定义。CDF 的导数即 PDF(概率密度函数):把 CDF 的 Y 轴切分成许多小段,取每段两端 X 值的差作为新 X 轴,就能得到类似正态分布旋转 90° 的 PDF 曲线。但中位数附近的密度往往远高于其他区域,会把长尾压得非常平、难以阅读,因此系统更倾向于用 CDF 而非 PDF 展示分布。

判断 CDF 曲线好坏的两条简单规则

  • 越平越好:理想 CDF 是水平直线,意味着没有等待、拥塞或停顿——实践中几乎不可能;
  • 99% 到 100% 之间的面积越小越好:99% 右侧就是长尾区域,对 SLA 影响显著。

实践中,缓慢上升且长尾面积小的 CDF 曲线是最理想的形态。

百分位随时间曲线:定位性能回退

百分位随时间曲线包含四条曲线:X 轴是时间,Y 轴从上到下分别是 99.9%、99%、90%、50% 分位值,颜色由橙到黄逐渐变浅。

鼠标悬停可以看到对应时刻的值。例如图上 tooltip 的含义是"39 秒前的 99% 延迟分位为 330 微秒"。该图刻意不包含 99.99-ile 曲线,因为它通常显著高于其他曲线,会把其他曲线压得难以阅读;如需单独查看 99.99-ile,可以点击名称以_latency_9999结尾的 bvar。这类图展示了分位数随时间的变化,非常适合分析系统的性能回退(performance regression)。

brpc 自动计算的延迟指标

brpc 会自动为服务计算延迟分布,无需用户手工添加。这些指标会出现在/vars中,例如:

从源码看,这套指标由bvar::LatencyRecorder支撑。src/bvar/latency_recorder.h 显示它内部聚合了多个子 bvar:

  • _latencyIntRecorder):平均延迟;
  • _max_latencyMaxer<int64_t>):最大延迟;
  • _latency_percentilePercentile):分位数原始数据;
  • _latency_p1/_p2/_p3/_999/_9999PassiveStatus<int64_t>):50%、75%(p2/p3 由bvar_latency_p1/p2/p3三个 gflag 决定具体分位)、99.9%、99.99% 分位值;
  • _latency_cdfCDF):可绘制的 CDF 数据;
  • _latency_percentilesPassiveStatus<Vector<int64_t, 4>>):分位数组。

expose(prefix)后会生成以prefix为前缀的一族变量,如xxx_latencyxxx_max_latencyxxx_countxxx_qpsxxx_latency_percentilesxxx_latency_cdf等(见 src/bvar/latency_recorder.h 的注释与实现)。百分位底层基于 src/bvar/detail/percentile.h 的PercentileInterval:延迟被采样进固定大小的区间,查询时升序排序后按下标取值(get_sample_at),并通过"合并时每个样本以近似等概率保留"的策略在内存与精度之间取得平衡。

bvar::LatencyRecorder可以对任意代码段计算延迟分布,用法如下(详见 docs/en/bvar_c++.md):

#include <bvar/bvar.h> ... bvar::LatencyRecorder g_latency_recorder("client"); // expose 该 recorder ... void foo() { ... g_latency_recorder << my_latency; // 记录一次延迟 ... }

如果应用已经启动了 brpc server,就可以在/vars中看到client_latencyclient_latency_cdf等指标,点击即可查看动态刷新的曲线:

非 brpc server 场景:dummy server

如果你的程序只使用 brpc client,甚至完全不使用 brpc,但仍想通过网页查看 bvar 曲线,有两种方式(见 docs/cn/dummy_server.md):

  1. 仅使用 brpc client:在程序运行目录下创建一个名为dummy_server.port的文件,内容写一个端口号(如 8888)。程序启动后会自动在该端口起一个空 server(dummy server),进程内所有 bvar 都可以通过其内置服务查看。

  2. 完全不用 brpc:需要手动添加 dummy server。先参考 docs/en/getting_started.md 完成编译接入,然后在程序入口加入:

#include <brpc/server.h> ... int main() { ... brpc::StartDummyServerAt(8888/*port*/); ... }

延伸:将 bvar 导出到 Prometheus 与本地文件

/vars只是 bvar 消费方式的一种。bvar 还支持把指标导出到 Prometheus:将 Prometheus 抓取目标的路径设为/brpc_metrics即可。例如 brpc server 运行在localhost:8080,则抓取地址配置为127.0.0.1:8080/brpc_metrics。其实现位于 src/brpc/builtin/prometheus_metrics_service.cpp,通过PrometheusMetricsDumper将 bvar 输出为 Prometheus 文本格式。

同时 bvar 支持按固定周期把全部已暴露变量写入本地文件(默认关闭)。控制它的 gflag 定义在 src/bvar/variable.cpp:

gflag默认值作用
bvar_dumpfalse开启后台线程周期性 dump 所有 bvar;关闭时所有bvar_dump_*均不生效
bvar_dump_exclude""按逗号分隔的通配符排除某些 bvar,空表示不排除
bvar_dump_filemonitor/bvar.<app>.datadump 输出的文件路径
bvar_dump_include""按逗号分隔的通配符只保留匹配的 bvar,空表示全部
bvar_dump_interval10两次 dump 之间的间隔(秒)
bvar_dump_prefix<app>每个 dump 出的名字附加的前缀
bvar_dump_tabslatency=*_latency*...按过滤器把 bvar 分到不同的 tab(格式:tab_name=wildcards,分号分隔)

注意这些 gflag 大多注册了校验器/回调(validate_bvar_dumpwakeup_dumping_thread),建议通过命令行参数-bvar_dump=truegoogle::SetCommandLineOption()动态修改,而不要直接赋值FLAGS_bvar_dump_file等 std::string 类型的 gflag——前者会触发校验与唤醒 dump 线程,后者既存在线程安全问题也不会让导出线程生效。dump 文件与普通日志不同:每次导出会覆盖之前的文件,而不是追加

总结

  • brpc 默认暴露全部 bvar,/vars是统一的查询入口:支持精确名、多名称(;/,/空格分隔)与通配符(*多字符、$单字符);
  • 数值型 bvar 可点击查看 60 秒/60 分钟/24 小时/30 天共 174 个采样点构成的历史趋势,数据布局见 src/bvar/detail/series.h;
  • 延迟类指标由bvar::LatencyRecorder自动计算(平均、最大、QPS、count、50%/90%/99%/99.9%/99.99% 分位与 CDF),普通代码段也可用同一工具自行埋点;
  • 长尾(99% 之后)是 SLA 的最大威胁,CDF 越平、长尾面积越小越好;
  • 只跑 client 或完全不用 brpc 的程序,可通过 dummy server 获得同样的可视化能力;生产环境还可借助/brpc_metrics对接 Prometheus。
  • RPC框架
  • 后端
  • 微服务
  • 网络
  • 通信

【免费下载链接】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".

项目地址:https://gitcode.com/gh_mirrors/brpc6/brpc
点击查看免费下载

相关推荐

上一篇:DataV 项目推荐
下一篇:DataV 开源项目常见问题解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/22 6:18:34

用异步SRAM替代SDRAM做EMC整改:从噪声源定位到滤波重设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/22 1:19:29

RadixAttention优化KV Cache:大模型推理显存降低70%

1. 项目概述&#xff1a;当KV Cache遇上RadixAttention最近在优化大语言模型推理性能时&#xff0c;我注意到SGLang提出的RadixAttention方案在KV Cache管理上做了些有意思的设计。传统KV Cache随着上下文增长线性膨胀的问题&#xff0c;相信每个做过LLM推理优化的同学都深有体…

作者头像 李华
网站建设 2026/9/22 0:41:52

SpringBoot戒烟管理系统设计与实现

1. 项目背景与核心价值作为一名长期关注健康科技领域的开发者&#xff0c;我发现戒烟辅助系统在公共卫生领域有着巨大潜力。这个基于SpringBoot的戒烟管理系统正是针对这一需求设计的毕业设计项目&#xff0c;项目编号24391表明它可能来自某高校的计算机专业课题库。这类系统通…

作者头像 李华
网站建设 2026/9/22 0:36:38

Python基础算法实战:平方和与鸡兔同笼问题解析

1. Python基础算法实战&#xff1a;从平方和到鸡兔同笼作为一名Python开发者&#xff0c;我经常遇到初学者在学习基础语法后不知道如何应用的问题。今天我就通过三个经典算法题目&#xff0c;带大家从零开始掌握Python的基础编程思维。这些题目看似简单&#xff0c;但包含了循环…

作者头像 李华
网站建设 2026/9/21 23:44:50

SpringBoot+Vue实现模特公司活动管理系统开发

1. 项目背景与核心需求模特公司活动组织系统是一个典型的B/S架构企业级应用&#xff0c;需要同时解决后台业务逻辑处理和前端用户交互的需求。这个系统主要面向模特经纪公司的日常运营管理&#xff0c;涉及模特资料管理、活动排期、客户对接、财务结算等核心业务流程。在技术选…

作者头像 李华