十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

brpc rpc_replay 请求采样与回放实战:从线上流量采集到协议级压测还原

brpc rpc_replay 请求采样与回放实战:从线上流量采集到协议级压测还原 brpc rpc_replay 请求采样与回放实战从线上流量采集到协议级压测还原【免费下载链接】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/brpcbrpcbetter RPC自 r31658 版本起内置了请求采样与回放能力服务端可以按概率把一部分真实请求落盘保存随后通过rpc_replay工具把这些请求原样回放到目标服务实现基于线上真实流量的回归测试、故障复现与性能压测。本文以 docs/cn/rpc_replay.md 为主线结合 src/brpc/rpc_dump.cpp、src/brpc/rpc_dump.h 与 tools/rpc_replay/rpc_replay.cpp 等源码实现完整讲解采样参数配置、落盘文件格式、二次开发接口与回放工具的每一个命令行参数读完即可在自己的服务上搭建一条采样 → 读取 → 回放的完整链路。一、整体原理采样端与回放端的分工rpc_replay 体系由两个相对独立的部分组成采样端被测试的服务进程brpc 以一定概率把经过服务的请求随机写入本地文件。采样由bvar::Collector统一调度见 src/bvar/collector.h来自不同线程的被采样请求被汇总后由后台线程批量写盘不同线程之间没有竞争开销很小。回放端tools/rpc_replay工具读取采样目录下的所有文件把序列化的请求重新发往指定 server。回放工具会为每种协议建立独立 Channel并按采样时的协议类型自动选择对应协议发送见下文 ChannelGroup 说明。目前采样与回放支持的协议有baidu_std、hulu_pbrpc、sofa_pbrpc、http、nshead。注意一个采样文件可能包含多种协议的请求——当 server 同时被多种协议访问时即是如此。回放时目标 server 也会相应收到不同协议的请求回放工具通过每个样本元数据中的protocol_type区分并分发。二、获取与编译工具先按照 Getting Started 编译好 brpc再进入tools/rpc_replay目录编译回放工具。仓库中该目录包含 Makefile、CMakeLists.txt 以及源码 rpc_replay.cpp、info_thread.cpp信息打印线程。在 CentOS 6.3 上如果出现找不到libssl.so.4的错误可执行ln -s /usr/lib64/libssl.so.6 libssl.so.4临时解决。三、采样如何把线上请求写入文件brpc 通过如下几个 flag 打开和控制请求保存包含 (R) 后缀的 flag 都可以动态设置即运行时通过-flagvalue或 brpc 的配置修改接口热更新。flag默认值说明-rpc_dumpfalse主开关关闭时其他以rpc_dump开头的 flag 全部无效-rpc_dump_dir./rpc_data/rpc_dump/app存放被 dump 请求的目录app会被替换为程序名-rpc_dump_max_files32目录下的最大文件数超过后删除最老的文件腾出空间-rpc_dump_max_requests_in_one_file1000一个文件内的最大请求数超过后写入新文件上表默认值可在 src/brpc/rpc_dump.cpp 的 flag 定义中确认其中rpc_dump_max_files与rpc_dump_max_requests_in_one_file还通过BRPC_VALIDATE_GFLAG注册了正整数校验。打开-rpc_dump后brpc 会以一定概率采集请求。如果服务的 QPS 很高brpc 会自动调节采样比例使得每秒钟采样的请求个数不超过-bvar_collector_expected_per_second对应的值。该值定义于 src/bvar/collector.cpp默认 1000由bvar::CollectorSpeedLimit负责限速见 src/bvar/collector.h 中BVAR_COLLECTOR_SPEED_LIMIT_INITIALIZER的使用。目前该值同样影响 rpcz 和 contention profiler一般不用改动以后会对不同的应用独立开来。采样入口的判定逻辑在 src/brpc/rpc_dump.h 的AskToBeSampled()中只有FLAGS_rpc_dump为真且bvar::is_collectable(g_rpc_dump_sl)通过限速检查时请求才会被采样被采样的请求封装为SampledRequest内含butil::IOBuf request与RpcDumpMeta meta由后台收集线程批量写入文件。3.1 采样目录与文件命名写出的内容依次存放在rpc_dump_dir目录下的多个文件内。该目录默认在./rpc_dump_app注意flag 的默认值是./rpc_data/rpc_dump/app其中的app占位符在 src/brpc/rpc_dump.cpp 的SaveFlags()中被替换为程序名。不同程序在同一个目录下同时采样时会写入不同的目录。如果程序启动时rpc_dump_dir已经存在目录将被清空见 src/brpc/rpc_dump.cppRpcDumpContext构造时执行butil::DeleteFile(_dir, true)。目录中的每个文件以requests.yyyymmdd_hhmmss_uuuuus命名DUMPED_FILE_PREFIX为requests见 src/brpc/rpc_dump.cpp时间戳精确到微秒并保证单调递增若当前时间不大于上一个文件的时间戳则强制1见 src/brpc/rpc_dump.cpp以保证按时间有序、方便查找。目录下的文件数不超过rpc_dump_max_files超过后最老的文件被删除src/brpc/rpc_dump.cpp 用std::dequestd::string _filenames记住最老文件并逐个删除。3.2 落盘文件的二进制格式文件是二进制格式格式与 baidu_std 协议的二进制格式类似每个请求的 binary layout 如下PRPC (4 bytes magic string) body_size(4 bytes) meta_size(4 bytes) RpcDumpMeta (meta_size bytes) serialized request (body_size - meta_size bytes, including attachment)请求之间紧密排列一个文件内的请求数不超过rpc_dump_max_requests_in_one_file。上述布局由 src/brpc/rpc_dump.cpp 的RpcDumpContext::Serialize()实现先预留 12 字节头部序列化RpcDumpMeta后追加原始请求体最后回填PRPCmagic、body_sizemeta request 总长与meta_size。写入采用批量缓冲策略src/brpc/rpc_dump.cpp未写完的数据先累积在_unwritten_buf上限 1MB满足当前文件请求数达上限 / 缓冲超过 1MB / 距上次写入超过 2 秒任一条件时才真正落盘避免每条请求都触发一次磁盘 IO。3.3 元数据结构RpcDumpMeta每个样本的元数据是 protobuf 消息brpc::RpcDumpMeta定义在 src/brpc/rpc_dump.proto关键字段及其适用协议如下字段类型适用协议含义service_namestringbaidu_std, hulu_pbrpc服务名method_namestringbaidu_std, sofa_pbrpc(full_method_name)方法名method_indexint32hulu_pbrpc方法索引compress_typeCompressTypebaidu_std, hulu_pbrpc, sofa_pbrpc压缩类型protocol_typeProtocolType全部协议类型attachment_sizeint32baidu_std, hulu_pbrpcattachment 大小authentication_databytesbaidu_std鉴权数据user_databyteshulu_pbrpc用户数据nsheadbytesnsheadnshead 头回放时正是依据这些字段恢复协议上下文如 nshead 协议直接把meta.nshead()拷回NsheadMessage.head保证原样重放。3.4 用 SampleIterator 做二次开发brpc 提供SampleIterator定义在 src/brpc/rpc_dump.h从一个采样目录下的所有文件中依次读取所有被采样请求用户可根据需求把 serialized request 反序列化为 protobuf 请求做一些二次开发#include brpc/rpc_dump.h ... brpc::SampleIterator it(./rpc_data/rpc_dump/echo_server); for (brpc::SampledRequest* req it-Next(); req ! nullptr; req it-Next()) { ... // req-meta的类型是brpc::RpcDumpMeta定义在src/brpc/rpc_dump.proto // req-request的类型是butil::IOBuf对应格式说明中的serialized request // 使用结束后必须delete req。 }从源码看SampleIterator内部通过butil::FileEnumerator枚举目录文件每次从当前 fd 追加最多 512KB 数据到_cur_buf并调用静态方法Pop()解析出一条请求Next()返回nullptr表示所有 dump 文件已读完。文档注释特别强调采样返回的顺序不保证与文件内存储顺序一致且每个返回的SampledRequest*必须由调用方delete。四、回放rpc_replay 工具的使用brpc 在 tools/rpc_replay 提供了默认的回放工具。运行时通过 gflags 传入参数main中调用GFLAGS_NAMESPACE::ParseCommandLineFlags解析见 tools/rpc_replay/rpc_replay.cpp。4.1 命令行参数详解参数默认值说明-dir空必填存放采样文件的目录为空或目录不存在时直接报错退出-times1循环回放次数-qps0大于 0 时限制 QPS默认为 0不限制-thread_num0发送线程数为 0 时根据 QPS 自动调节一般不用设置-use_bthreadtrue使用 bthread 发送为 false 时改用 pthread-connection_type连接 server 的方式默认按协议自动选择-server0.0.0.0:8002server 的地址-load_balancer负载均衡算法-timeout_ms100RPC 超时毫秒-max_retry3最大重试次数-dummy_port8899dummy server 的端口监控回放状况-http_host指定回放 HTTP 请求时的 Host 字段若为非标准端口请补全例如www.abc.com:8888不指定时使用采样的原始 Host 字段所有参数默认值均可在 tools/rpc_replay/rpc_replay.cpp 的DEFINE_*中核对其余参数可加上--help运行查看。其中几个参数的底层逻辑值得展开-thread_num自动调节当thread_num 0时若不限 QPS 则固定用 50 个线程若限 QPS则取qps / 10000并夹在 150 之间tools/rpc_replay/rpc_replay.cpp。另外单线程速率上限为 100 万 QPS超限会报错退出tools/rpc_replay/rpc_replay.cpp。协议分发 ChannelGroupChannelGroup::Init()通过brpc::ListProtocols()枚举所有协议为同时支持客户端和服务端的每种协议各建一个 Channel每个样本按其meta.protocol_type()取对应 Channel 发送tools/rpc_replay/rpc_replay.cpp。各协议请求还原HTTP 样本解析HttpMessage并把 Host 替换为-http_host若指定nshead 样本还原 nshead 头带 attachment 的样本按attachment_size切分请求体与 attachmenttools/rpc_replay/rpc_replay.cpp。QPS 限速实现限速时采用期望发送时间节流允许的最大容忍延迟为 10ms 或 10 个发送间隔中较大者追不上则重置期望时间tools/rpc_replay/rpc_replay.cpp失败时回放线程会bthread_usleep(10000)短暂休眠避免 server 宕机时 bthread 被持续创建而饿死tools/rpc_replay/rpc_replay.cpp。4.2 dummy server 监控与命令行输出rpc_replay默认启动一个仅监控用的 dummy server当-dummy_port 0时调用brpc::StartDummyServerAt启动默认端口 8899打开后可在浏览器中查看回放状况其中rpc_replay_error是回放失败的次数对应源码中的bvar::Adderint64_t g_error_count(rpc_replay_error_count)见 tools/rpc_replay/rpc_replay.cpp。如果无法打开浏览器命令行中也会定期打印信息由 tools/rpc_replay/info_thread.cpp 的InfoThread每秒输出一次2016/01/30-16:19:01 sent:101 success:101 error:0 total_error:0 total_sent:28379 2016/01/30-16:19:02 sent:101 success:101 error:0 total_error:0 total_sent:28480 2016/01/30-16:19:03 sent:101 success:101 error:0 total_error:0 total_sent:28581 2016/01/30-16:19:04 sent:101 success:101 error:0 total_error:0 total_sent:28682 2016/01/30-16:19:05 sent:101 success:101 error:0 total_error:0 total_sent:28783 2016/01/30-16:19:06 sent:101 success:101 error:0 total_error:0 total_sent:28884 2016/01/30-16:19:07 sent:101 success:101 error:0 total_error:0 total_sent:28985 2016/01/30-16:19:08 sent:101 success:101 error:0 total_error:0 total_sent:29086 2016/01/30-16:19:09 sent:101 success:101 error:0 total_error:0 total_sent:29187 2016/01/30-16:19:10 sent:101 success:101 error:0 total_error:0 total_sent:29288 [Latency] avg 122 us 50% 122 us 70% 135 us 90% 161 us 95% 164 us 97% 166 us 99% 172 us 99.9% 199 us 99.99% 199 us max 199 us上方的字段含义是自解释的sent/success/error是最近 10 秒的发送数、成功数与失败数total_error/total_sent是累计值。下方是延时信息每 10 秒打印一次完整延时表第一项avg是 10 秒内的平均延时最后一项max是 10 秒内的最大延时其余以百分号结尾的项是延时分位值即有左侧这么多比例的请求延时小于右侧的延时单位微秒。性能测试需要重点关注 99% 之后的长尾区域99.9%、99.99% 与 max它们往往最能反映系统在高负载下的稳定性。五、实战要点与最佳实践先开采样再谈回放采样是回放的数据来源。在压测或灰度环境先以-rpc_dump开启采样跑一段时间收集覆盖典型场景的请求QPS 高时系统会自动降采样无需手动调比例。目录与文件管理采样目录默认按程序名隔离且进程启动时会清空旧目录因此重启服务前务必先备份已采样的目录文件数超限会自动淘汰最老的可通过调大-rpc_dump_max_files延长保留窗口。回放目标的选择-server指定目标地址-timeout_ms/-max_retry控制超时与重试建议先用默认参数小流量验证如-qps 100确认error为 0 后再放大 QPS。HTTP 回放注意 Host回放 HTTP 请求时若目标环境的 Host 与采样时不同务必用-http_host显式指定非标准端口要补全端口号否则可能因 Host 不匹配导致路由或鉴权失败。混合协议场景一个采样文件可能混有多种协议回放工具会自动按protocol_type分发到对应 Channel无需人工拆分文件。二次开发需要统计、改写或清洗请求时直接用SampleIteratorRpcDumpMeta读取样本注意每个SampledRequest*使用完毕后必须delete。六、总结rpc_replay 为 brpc 服务提供了一条零侵入采集真实流量 → 协议级原样回放的完整链路采样端借助bvar::Collector与后台批量写盘把开销降到最低落盘文件采用自描述的PRPC二进制格式并携带RpcDumpMeta元数据回放端rpc_replay工具自动按协议建 Channel、支持 QPS 限速、bthread 并发、HTTP Host 覆盖并通过 dummy server 与命令行双通道输出实时成功率与延时分位数据。无论是线上故障复现、回归测试还是基于真实流量的压测这套机制都能让开发者以最接近生产的方式验证服务行为。更深入的实现细节可继续阅读 src/brpc/rpc_dump.cpp、src/brpc/rpc_dump.h、src/brpc/rpc_dump.proto 与 tools/rpc_replay/rpc_replay.cpp 的源码与注释。【免费下载链接】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),仅供参考
返回列表