用户态探针
用户态探针在应用程序的函数上插桩,观测调用频率与返回耗时。它不需要重启应用、不需要改代码、也不依赖应用自带埋点,对第三方组件尤为实用。目标可以是二进制的符号名,也可以是符号缺失时的地址偏移。
基本信息
| 适用平台 | Linux,需要内核 eBPF 支持与相应权限 |
|---|---|
| 目标形式 | 二进制路径加符号名,或路径加偏移 |
| 符号要求 | 符号需存在于二进制,或被剥离时改用偏移 |
| 开销 | 高频热函数插桩会明显增加开销 |
| 稳定性 | 二进制更新后符号与偏移可能变化 |
典型使用场景
- 观测第三方组件内部函数的调用频率,缺少官方指标时尤其有用。
- 统计业务关键函数的调用次数,验证上线后的实际路径。
- 测量函数耗时分布,定位比预期慢的那一类调用。
- 确认某个配置开关对应的代码分支是否被走到。
- 在无法重新部署的环境里做只读观测。
用法
用法
bpftrace -e 'uprobe:/opt/app/bin/server:handle_request { @ = count(); }' # 调用次数
bpftrace -e 'uprobe:/opt/app/bin/server:handle_request { @start[tid] = nsecs; }
uretprobe:/opt/app/bin/server:handle_request { @ns = hist(nsecs - @start[tid]); delete(@start[tid]); }' # 耗时分布
nm -D /opt/app/bin/server | grep -i handle_request # 先确认符号是否存在
readelf -sW /opt/app/bin/server | grep -c FUNC # 查看符号表规模
bpftrace -e 'uprobe:/opt/app/bin/server:0x1234 { @ = count(); }' # 无符号时用偏移指定方式
| 形式 | 写法 | 适用情况 |
|---|---|---|
| 按符号名 | 路径加冒号加函数名 | 二进制保留符号表 |
| 按偏移 | 路径加冒号加十六进制地址 | 符号被剥离或静态符号 |
| 动态库函数 | 库文件路径加符号名 | 观测依赖库内部行为 |
插桩的是内存中的一份二进制:应用发布新版本后,之前写死的符号与偏移需要重新核对,否则探针会挂到错误位置或直接失效。
语言运行时的即时编译代码与动态生成的函数通常不在二进制符号表里,这类目标挂不上用户态探针;需要观测时应改用运行时提供的追踪机制或日志埋点。
对高频热函数插桩会显著放大开销:先用计数模式小窗口试跑,确认影响可接受后再测量耗时分布。