基于 eBPF/BCC的性能调优利器 func_latency:内核/用户函数耗时精准统计,性能专家必备神器!

一、引言

在复杂的系统性能调优过程中,函数执行耗时的精准统计与分析是定位性能瓶颈的核心环节。无论是内核态函数,还是用户态业务函数,了解它们的真实运行时间,才能为优化决策提供科学依据。然而,现有的性能分析手段往往存在采样粒度不足、参数过滤不灵活、关联调用链追踪困难等瓶颈,导致性能问题难以精准定位,调优过程耗时且低效。 针对这一痛点,本人自主研发了 func_latency 工具,专注于函数级耗时统计分析。它支持内核函数、用户函数、以及 tracepoint 的多源联合追踪,能够灵活提取函数参数,支持复杂的条件过滤,并可结合调用栈信息进行深度剖析。通过这些能力,func_latency 实现了从函数执行时间到调用上下文的全方位透视,极大提升了性能调优的效率和精度。

本文将详细介绍 func_latency 的功能特点和使用方法,并通过实战示例展示其在真实场景中的应用价值,助力性能专家更快更准地定位系统瓶颈。

二、func_latency 是什么?

这是一款基于 BCC 技术实现的 eBPF 工具,功能总览如下表所示:

功能点 支持情况
支持内核函数 ✅ 通配/正则匹配
支持用户函数(uprobe)
支持 tracepoint
参数提取 ✅ 任意类型、结构体
参数过滤 ✅ 按值、结构体成员
栈信息打印 ✅ 可选
输出格式 ✅ 普通 / 直方图
指定 PID/TID
定时输出 / 限时运行
多函数组合分析 ✅ 如 从func1至func2的耗时分析`

三、基本使用示例

✅ 示例 1:测量所有以 vfs_ 开头的内核函数的执行时间

root@instance-bguv65e0 bpf_perf_tools\]# python3 ./func_latency 'vfs_read\*' -Ti 1

结果说明:

每秒会输出一次当秒内核函数vfs_read*的调用耗时情况,以线程号来区分,统计信息有:

AVG_LATENCY(ns):平均耗时,单位纳秒;

MAX_LATENCY(ns):最大耗时,单位纳秒;

MIN_LATENCY(ns):最小耗时,单位纳秒;

MAX_INDEX:最大耗时是第几次调用;

COUNT:总共调用了多少次。
参数说明:

-T,输出的结果中显示时间;

-i,输出结果的时间间隔,此例中是1秒输出一次。

✅ 示例 2:只分析 以vfs_开头的内核函数,并且只记录耗时 50us ~ 10ms 的调用

root@instance-bguv65e0 bpf_perf_tools\]# python3 ./func_latency 'vfs_\*' -m 50000 -M 1000000 -Ti 1

参数说明:

-m:过滤最小耗时,低于此值,不统计;

-M:过滤最大耗时,高于此值,不统计。

✅ 示例 3:测量从syscalls:sys_enter_write至syscalls:sys_exit_write之间的耗时

root@instance-bguv65e0 bpf_perf_tools\]# python3 ./func_latency 't:syscalls:sys_enter_write;t:syscalls:sys_exit_write' -Ti 1

✅ 示例4:内核函数tcp_v4_connect耗时,并获取参数sa_family和addr_len的值

root@instance-bguv65e0 bpf_perf_tools\]# python3 ./func_latency 'tcp_v4_connect' -Ti 1 -args 'ushort arg2-\>0,uint32_t arg3:'

结果说明:

函数原型:int tcp_v4_connect(struct sock *sk, struct sockaddr uaddr, int addr_len)
struct sockaddr的定义为:
struct sockaddr {
unsigned short sa_family; /
address family, AF_xxx /
char sa_data[14]; /
14 bytes of protocol address */

};

所以要想获取sa_family的值,则需要从第二个参数uaddr的偏移量为0处开始取2字节(unsigned short),且还需要取第三个参数,对应脚本参数表达式"-args 'ushort arg2->0,uint32_t arg3:'"。

✅ 示例5:C++用户态函数耗时,并获取参数中成员a的值

首先,编译并运行以下demo程序;

cpp 复制代码
// test.cpp
#include <iostream>
#include <thread>
#include <chrono>
#include <cstdlib>
struct double_t
{
    double data;
};
typedef struct double_wrapper
{
    double_wrapper() { dp = new double_t(); }
    ~double_wrapper() { delete dp; }
    uint32_t a;
    double_t d;
    double_t* dp;
} double_w_t;
double uprobe_sum_dw_ref(const double_w_t& d1, const double_w_t& d2)
{
    printf("d1.a = %u,d2.a = %u, d1.d.data = %lf, d2.d.data = %lf, d1.dp->data = %lf, d2.dp->data = %lf\n",
        d1.a, d2.a, d1.d.data, d2.d.data, d1.dp->data, d2.dp->data);
    return d1.dp->data + d2.dp->data;
}
int main()
{
    srand((int)time(0));
    while(1) {
        double_w_t d1, d2;
        d1.a = rand();
        d1.d.data = rand() + (double)rand() / RAND_MAX;
        d1.dp->data = rand() + (double)rand() / RAND_MAX;
        d2.a = rand();
        d2.d.data = rand() + (double)rand() / RAND_MAX;
        d2.dp->data = rand() + (double)rand() / RAND_MAX;
        auto ret = uprobe_sum_dw_ref(d1, d2);
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
    return 0;
}
//编译命令:g++ test.cpp -g -o test

root@instance-bguv65e0 bpf_perf_tools\]# python3 ./func_latency ./test:*uprobe_sum_dw_ref* -Ti 1 -args 'uint32_t arg1-\>0,uint32_t arg2-\>0:' ![uprobe](https://oss.xyyzone.com/jishuzhan/article/1954362640683282434/d2349b87e9b4bb19d1ee12d93c70b508.webp)

结果说明:

在struct double_wrapper结构体中,成员a的偏移量为0,长度为4字节,对应指令参数"-args 'uint32_t arg1->0,uint32_t arg2->0:'",要监测的语法是bin文件路径:函数符号,这里由于是C++语言,函数符号会在函数名的基础上加以填充,所以在函数名前后加星号,使用正则来匹配。

四、如何获取脚本?

func_latency 是本人自研的性能工具,可免费使用,版权所有,请匆传播发放或用于商业用途,为了更好地维护、更新和支持使用者,目前采用 私密发放 的方式。

📌 获取方式如下:

1️⃣ 关注我的微信公众号:Hankin-Liu的技术研究室

2️⃣ 发送关键词:func_latency

3️⃣ 获取脚本

4️⃣ 加入技术交流群

五、写在最后

BCC + eBPF 是当前 Linux 性能诊断的最强组合,而 func_latency 则是我基于实战需求精心打磨的利器。 无论你是内核工程师、运维专家,还是系统性能爱好者,都值得拥有这把"时间分析的瑞士军刀"。

📬 有任何使用问题,也欢迎公众号(Hankin-Liu的技术研究室)后台留言,我会亲自答复!

相关推荐
只因在人海中多看了你一眼7 小时前
B.10.01.3-性能优化实战:从JVM到数据库的全链路优化
jvm·数据库·性能优化
嫩萝卜头儿7 小时前
AWT 事件监听器深入浅出:Action/Mouse/Key/Window 全解析与实战
java·开发语言·性能优化
FogLetter7 小时前
解放主线程!Web Worker 让你的前端应用飞起来
前端·性能优化
今禾7 小时前
🌐 深入解析 Web Worker:突破 JavaScript 单线程限制
前端·javascript·性能优化
国科安芯20 小时前
质子试验:守护芯片安全的关键防线
嵌入式硬件·安全·fpga开发·性能优化·硬件架构
嫩萝卜头儿20 小时前
从零掌握 Java AWT:原理、实战与性能优化
java·开发语言·性能优化
嫩萝卜头儿1 天前
深入理解 Java AWT Container:原理、实战与性能优化
java·python·性能优化
Live&&learn1 天前
seo-使用nuxt定义页面标题和meta等信息
vue.js·性能优化
摘星编程1 天前
Agent配置最佳实践:Prompt工程与参数调优
性能优化·prompt工程·参数调优·智能体开发·agent配置