brpc /vars 指标监控完全指南:bvar 查询、通配符匹配与延迟百分位分析
【免费下载链接】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/gh_mirrors/brpc3/brpc点击查看免费下载brpc 内置的 bvar 指标系统src/bvar将所有暴露的计数器通过内置 HTTP 服务/vars统一对外提供是排查线上服务性能、追踪延迟长尾与量化 SLA 的关键入口。本文围绕 vars.md 的内容系统讲解/vars的查询方法精确名、逗号列表、通配符、$单字符匹配、历史趋势与 CDF/分位曲线解读并结合 LatencyRecorder 等源码说明如何为任意代码段产出_latency_999、_latency_cdf等指标让读者能直接在 brpc 服务上落地这套监控方案。bvar 是什么为什么 brpc 默认集成它文档 开门见山地给出定义bvar 是一组用于在多线程应用中方便地记录与查看各类统计值的计数器。其核心实现通过**线程局部存储Thread Local Storage, TLS**减少缓存抖动cache bouncing每个线程只写自己的私有区域不参与全局竞争读取时再合并所有线程的数据。因此在竞争激烈的场景下bvar 的写入速度远快于百度内部的旧计数库 UbMonitor甚至快于原子操作——文档给出的参考数据是 bvar 单次操作开销约 20 纳秒且与线程数基本无关而动态 UbMonitor 在 24 线程时单次操作约 7 微秒约为 bvar 的 300 倍开销。与之对应的是 bvar 设计文档 中的一句话bvar 本质上是把写时的竞争转移到了读时。读操作需要把所有线程写入的数据合并起来因此比普通读慢得多。这也划定了 bvar 的适用边界——如果对计数器的读写都非常频繁或需要基于最新值做决策就不应该使用 bvar它更适用于低频的日志采集与监控展示场景。brpc 默认集成 bvar只要启动一个 brpc 服务所有暴露的 bvar 都会自动注册到全局变量表参见 Variable::expose / dump_exposed 等接口并通过内置的 VarsService 对外提供访问。这正是本文讨论的/vars页面的来源。如果你只是想为自己的程序找一个采集、展示指标的通用工具bvar 值得优先考虑而想了解如何为自己的程序添加 bvar可阅读 bvar 快速上手。查询方式/vars 支持的四种 URL 形态/vars由brpc::VarsService实现vars_service.cpp。服务将 URL 中的 unresolved path 作为DumpOptions::white_wildcards传给bvar::Variable::dump_exposed进行过滤见 vars_service.cpp因此 URL 即查询表达式。文档归纳了四种查询形态URL含义示例/vars列出所有暴露的 bvar/vars/vars/NAME列出名字为NAME的单个 bvar/vars/rpc_socket_count/vars/NAME1,NAME2,NAME3同时列出多个指定名字的 bvar/vars/pid;process_cpu_usage;rpc_controller_count/vars/foo*,b$r按通配符模式匹配一批 bvar/vars/rpc_server*_count;iobuf_blo$k_*关于通配符文档特别强调了一个易错点URL 中?是保留字符因此 bvar 使用$表示匹配单个字符而不是常见的?。这一约定与DumpOptions::question_mark字段对应——在 vars_service.cpp 中该字段被显式设为$variable.h 中的注释也说明The?in wildcards. Wildcards in URL need to use another character because?is reserved.模式可以用,、;或空格分隔多个表达式。值得一提的是*也是可通配字符且/vars页面会把输入自动规范化例如输入iobuf,bthread会被转换为*iobuf*;*bthread*见 vars_service.cpp 的toURL()函数。页面上的搜索框在/vars页面左上角有一个搜索框HTML 输入框见 vars_service.cpp可以输入名字片段来定位 bvar。不同模式同样以,、:或空格分隔。搜索通过?dataonly请求异步拉取并重绘页面vars_service.cpp。从终端访问 /vars/vars同样支持纯文本输出直接curl即可文档中给出的示例$ 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输出格式为每行名字 : 值。文本与 HTML 两种形态通过UseHTML(cntl-http_request())区分且各自套用不同的DisplayFilterDISPLAY_ON_HTML/DISPLAY_ON_PLAIN_TEXT见 vars_service.cpp——这意味着某些只适合图形展示的 bvar如 CDF 曲线、percentiles 向量可能只出现在 HTML 页面上而在纯文本输出中被过滤掉。从源码结构看文本输出还会按响应压缩设置走 GZIPvars_service.cpp。查看历史趋势可点击 bvar 背后的时间序列绝大多数数值型 bvar 都是可点击的——点击后会展示其历史趋势图。这一能力由 describe_series 提供服务器端通过/vars/NAME?series请求见 vars_service.cpp返回 JSON 格式的序列数据页面上的 flot.js 绘图脚本 每隔 1 秒轮询一次并实时刷新曲线。文档给出的关键量化指标每个可点击的 bvar 记录最近60 秒、60 分钟、24 小时、30 天四个时间窗的数据共计174个数值点1000 个可点击 bvar 大约占用1M 内存。这 174 个点也体现在绘图脚本的坐标轴刻度上——trendOptions中的 x 轴刻度为-1 day / -1 hour / -1 minutevars_service.cppdescribeTrendX()函数则按x 173 / x 113 / x 53 / x 29分段把序列索引换算为刚刚 / N 秒前 / N 分钟前 / N 小时前 / N 天前vars_service.cpp与 174 个采样点严格对应。需要说明的是历史趋势是否可点击由该 bvar 是否保存序列决定页面在渲染时调用Variable::describe_series_exposed探测vars_service.cpp返回 0 才判定为可绘图classvariable并附带一个空的 flot 占位图否则渲染为nonplot-variable。计算与查看分位数从 x-ile 到 CDF 曲线x-ile 的定义x-ile即第 x 百分位指在一组有序数值中排在第 N·x% 位的值。文档给出的例子时间窗内有 1000 个值按升序排列后第 500 个1000×50%就是 50-ile即中位数第 990 个1000×99%是 99-ile第 999 个是 99.9-ile。百分位比平均值携带更多延迟分布信息是分析系统行为的重要工具。文档特别强调工业级服务通常要求 SLA 不低于 99.97%百度内部二级服务要求一级服务甚至要求 ≥99.99%。即便系统平均延迟很优秀糟糕的长尾long-tail区域仍可能击穿 SLA——这正是百分位分析的价值所在。百分位可以绘制成两种图CDF 曲线和百分位随时间变化曲线。为什么是 CDF 而不是 PDFCDF累积分布函数图的 X 轴是比例排序位置/总数Y 轴是对应百分位的值。例如 X50% 对应的 Y 就是 50-ile。如果系统要求99.9% 的请求在 Y 毫秒内完成直接看 Y 在 99.9% 处的取值即可。为什么称之为 CDF因为当选定一个 Yy 时对应的 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的利器。绘图时使用独立的trendOptions调色板vars_service.cpp曲线颜色对应文档所述从橙到黄的渐变。自动计算的延迟分布指标LatencyRecorder 的源码级解剖brpc 会自动计算服务的延迟分布无需用户手动添加任何指标。文档列出了 bvar 自动产出的延迟指标族其命名模式在 latency_recorder.cpp 的expose()中逐一展开指标名prefix 为client时含义暴露的显示目标client_latency时间窗内平均延迟窗口由构造参数决定全部client_max_latency时间窗内最大延迟全部client_count累计记录的延迟次数全部client_qps每秒记录的延迟次数全部client_latency_80/client_latency_90/client_latency_99由bvar_latency_p1/p2/p3三个 gflag 控制的百分位默认 80/90/99仅纯文本client_latency_99999.9% 分位仅纯文本client_latency_999999.99% 分位全部client_latency_cdfCDF 曲线HTML 页面上点击查看仅 HTMLclient_latency_percentiles四元向量依次为 p1/p2/p3/99.9 分位仅 HTML从 LatencyRecorderBase 的成员布局 可以看到它的内部构成一个IntRecorder _latency记录延迟流、一个Maxerint64_t _max_latency记录最大值、一个Percentile _latency_percentile维护分位采样以及对应的Window化版本与多个PassiveStatus延迟、QPS、各分位、CDF 与 percentiles 向量。LatencyRecorder本身不是Variable而是一个复合变量——它内部包含多个 bvar。bvar_latency_p1/p2/p3三个 gflag 定义于 latency_recorder.cpp默认值 80/90/99并带有取值范围校验必须 0 100见 latency_recorder.cpp。命名规则在源码中有明确的_latency_%d拼接逻辑latency_recorder.cpp。CDF 曲线的数据生成在 latency_recorder.cpp把窗口内的分位采样合并CombinedPercentileSamples取 10%~90% 每隔 10%、91%~99% 每个整数、再加 99.9% 与 99.99% 共 20 个点输出为 JSON。这正好对应cdfOptions中 X 轴刻度[10%...99.99%]vars_service.cpp。用 LatencyRecorder 为任意代码段统计延迟文档给出的示例是定义前缀为client的LatencyRecorder#include bvar/bvar.h ... bvar::LatencyRecorder g_latency_recorder(client); // expose this recorder ... void foo() { ... g_latency_recorder my_latency; ... }只要程序启动了 brpc serverclient_latency、client_latency_cdf等值即可从/vars查看点击后能看到动态更新的曲线。写入是同步且廉价的——operator内部依次把延迟写入_latency、_max_latency和_latency_percentilelatency_recorder.cpp完全沿袭 bvar 的 TLS 低竞争设计。从 latency_recorder.h 可以看到LatencyRecorder支持多种构造形态LatencyRecorder()默认窗口由 dump 间隔决定LatencyRecorder(window_size)自定义时间窗秒数LatencyRecorder(prefix)构造即暴露LatencyRecorder(prefix1, prefix2)以两个片段拼接名字例如expose(foo_bar, read)会产出foo_bar_read_latency等LatencyRecorder(prefix, window_size)等组合形态。expose()对传入的 prefix2 做了容错处理如果用户传的名字以latency/Latency结尾会被自动去掉再拼接latency_recorder.cpp避免出现foo_latency_latency这样的名字。非 brpc server 场景如何查看曲线如果程序只使用了 brpc client、甚至完全没使用 brpc但又想看延迟曲线可以借助一个专门的伪服务器——启动一个dummy server即内部空服务它提供一个最小的 HTTP 端口来承载/vars等内置服务。详细做法参见 dummy server 说明。深度延伸bvar 的落地导出与 Prometheus 集成围绕/vars这套查询能力bvar 还提供了两条常用的数据出口可与/vars形成互补1. 定时 dump 到本地文件开启 bvar 的 dump 功能后所有暴露的 bvar 会被周期性写入文件格式与/vars纯文本输出一致每行名字 : 值。注意 dump 文件的语义新导出内容会覆盖旧文件这与常规日志追加的语义不同bvar.md 中明确说明。开启方法是在程序启动时传入 gflag-bvar_dump例如./your_server -bvar_dump或通过/flags内置服务动态修改。相关 gflag 汇总gflag默认值作用bvar_dumpfalse开启后台线程周期性 dump 所有 bvar关闭时所有bvar_dump_*失效bvar_dump_exclude按通配符逗号分隔排除的 bvar空表示无排除bvar_dump_filemonitor/bvar.app.datadump 输出文件bvar_dump_include按通配符逗号分隔只 dump 匹配的 bvar空表示包含全部bvar_dump_interval10两次 dump 之间的间隔秒数bvar_dump_prefixapp每个被 dump 的名字加此前缀bvar_dump_tabs见代码按过滤器分号分隔分 tab dump格式*(tab_namewildcards)2. 导出到 Prometheus如果希望接入 Prometheus 生态brpc 内置了PrometheusMetricsServiceprometheus_metrics_service.cpp。只需将 Prometheus 的抓取目标scraping target路径设为/brpc_metrics。例如 brpc server 运行在localhost:8080抓取目标就是127.0.0.1:8080/brpc_metrics。从源码看该服务会复用 bvar 的Dumper机制把指标转换为 Prometheus 文本格式普通数值型 bvar 输出为gauge而LatencyRecorder产生的整组延迟指标会被识别并合并输出为summary包含平均延迟、count 及 p1/p2/p3/99.9/99.99/max 等 6 个分位值见 prometheus_metrics_service.cpp。字符串型 bvar 会被跳过因为没有必要在 Prometheus 中监控字符串prometheus_metrics_service.cpp。小结从 /vars 出发构建监控闭环/vars是 brpc 服务可观测性的核心入口页面形态支持搜索框与通配符筛选终端形态支持 curl 快速抓取数值型 bvar 内置 60 秒/60 分钟/24 小时/30 天四档历史序列LatencyRecorder自动产出的_latency_999、_latency_9999、_latency_cdf等指标让延迟长尾与 SLA 达标情况一目了然。再加上文件 dump 与/brpc_metrics两条出口bvar 完全可以充当应用监控体系的数据底座。理解 CDF 曲线越平越好、99% 后面积越小越好的判读法则结合-bvar_dump、bvar_latency_p1/p2/p3等 gflag 的调优就能把 brpc 内置的这套指标系统用足、用好。赞分享【免费下载链接】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/gh_mirrors/brpc3/brpc点击查看免费下载相关推荐brpc 内置指标查询指南通过 /vars 监控 bvar 计数器与延迟分位数brpc 内置指标查询指南通过 /vars 监控 bvar 计数器与延迟分位数 brpc 默认集成 bvar 计数器库所有进程内暴露expose的 bvRPC框架后端微服务网络通信brpc /vars 内置服务完全指南bvar 计数器查询、分位值统计与延时分析实战brpc /vars 内置服务完全指南bvar 计数器查询、分位值统计与延时分析实战 导读本文围绕 brpc 内置的 /vars 服务展开系统讲解多线程计RPC框架后端微服务网络通信Forge响应验证功能确保LLM输出符合预期的强大工具Forge响应验证功能确保LLM输出符合预期的强大工具 在自托管LLM工具调用和多步骤代理工作流中 Forge响应验证功能 是确保AI助手可靠执行复杂任务的人工智能LLM 网关工具调用本地部署上一篇Claude for Office 直接云接入指南为 M365 插件配置 Vertex / Bedrock / 网关并生成定制 manifest下一篇DeepSeek Harness 客户端插件加载模型懒加载工厂、Cordis 生命周期与浏览器端热重载创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考