BPFtrace 动态追踪工具教程
BPFtrace 是基于 eBPF 技术的高级动态追踪工具,提供类似 AWK 的简洁语法来编写追踪脚本。与传统的 strace 不同,BPFtrace 直接在内核中执行追踪逻辑,对系统性能的影响极小,非常适合在搬瓦工 VPS 的生产环境中使用。本文将介绍 BPFtrace 的安装和各类实用追踪场景。
一、安装 BPFtrace
# Ubuntu 20.04+
apt update
apt install bpftrace -y
# Ubuntu(最新版本)
apt install -y bpftrace bpfcc-tools linux-headers-$(uname -r)
# CentOS 8+
yum install bpftrace -y
# 验证安装
bpftrace --version
# 检查内核是否支持 BPF
uname -r # 需要 4.9+,推荐 5.x+
二、BPFtrace 基础语法
BPFtrace 脚本的基本结构:probe /filter/ { action }
常用探针类型:
- kprobe/kretprobe:内核函数入口/返回。
- uprobe/uretprobe:用户空间函数入口/返回。
- tracepoint:内核静态追踪点。
- profile:定时采样。
- interval:定时输出。
- BEGIN/END:脚本开始/结束。
三、常用单行命令
3.1 进程追踪
# 追踪新创建的进程
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("exec: %s %s\n", comm, str(args->filename)); }'
# 统计各进程的系统调用次数
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
# 追踪进程退出及退出码
bpftrace -e 'tracepoint:sched:sched_process_exit { printf("exit: %s (pid=%d) code=%d\n", comm, pid, args->code >> 8); }'
3.2 文件 I/O 追踪
# 追踪文件打开操作
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("open: %s %s\n", comm, str(args->filename)); }'
# 按进程统计读取字节数
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret > 0/ { @bytes[comm] = sum(args->ret); }'
# I/O 延迟直方图
bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @us = hist((nsecs - @start[tid]) / 1000); delete(@start[tid]); }'
3.3 网络追踪
# 追踪 TCP 连接
bpftrace -e 'kprobe:tcp_connect { printf("connect: %s -> %s\n", comm, ntop(((struct sock *)arg0)->__sk_common.skc_daddr)); }'
# 追踪 TCP 接收数据量
bpftrace -e 'kprobe:tcp_recvmsg { @bytes[comm] = sum(arg2); }'
# TCP 重传追踪
bpftrace -e 'tracepoint:tcp:tcp_retransmit_skb { printf("retransmit: %s sport=%d\n", ntop(args->saddr), args->sport); }'
3.4 内存追踪
# 追踪内存分配大小分布
bpftrace -e 'tracepoint:kmem:kmalloc { @size = hist(args->bytes_alloc); }'
# 按进程统计页错误
bpftrace -e 'tracepoint:exceptions:page_fault_user { @[comm] = count(); }'
四、BPFtrace 脚本文件
4.1 TCP 连接延迟分析
cat > tcp-latency.bt <<'EOF'
#!/usr/bin/env bpftrace
BEGIN { printf("Tracing TCP connection latency...\n"); }
kprobe:tcp_v4_connect {
@start[tid] = nsecs;
}
kretprobe:tcp_v4_connect /@start[tid]/ {
$dur_us = (nsecs - @start[tid]) / 1000;
@latency_us = hist($dur_us);
if ($dur_us > 10000) {
printf("Slow connect: %s pid=%d %d us\n", comm, pid, $dur_us);
}
delete(@start[tid]);
}
END { clear(@start); }
EOF
bpftrace tcp-latency.bt
4.2 磁盘 I/O 延迟分析
cat > disk-latency.bt <<'EOF'
#!/usr/bin/env bpftrace
BEGIN { printf("Tracing block I/O latency...\n"); }
tracepoint:block:block_rq_issue {
@start[args->dev, args->sector] = nsecs;
}
tracepoint:block:block_rq_complete /@start[args->dev, args->sector]/ {
$dur = (nsecs - @start[args->dev, args->sector]) / 1000;
@us = hist($dur);
@avg_us = avg($dur);
delete(@start[args->dev, args->sector]);
}
EOF
bpftrace disk-latency.bt
4.3 HTTP 请求追踪
cat > http-trace.bt <<'EOF'
#!/usr/bin/env bpftrace
// 追踪 Nginx/Apache 的 read 系统调用来识别 HTTP 请求
tracepoint:syscalls:sys_exit_read
/comm == "nginx" && args->ret > 0/ {
@req_size = hist(args->ret);
@total_bytes = sum(args->ret);
@req_count = count();
}
interval:s:5 {
printf("\n--- Stats (5s interval) ---\n");
printf("Requests: %d\n", @req_count);
print(@req_size);
}
EOF
五、BPF 工具集(bcc-tools)
# 安装 BCC 工具集
apt install bpfcc-tools -y
# 常用工具:
# 追踪 TCP 连接事件
tcpconnect-bpfcc
# 追踪 TCP 接受连接
tcpaccept-bpfcc
# 追踪 TCP 重传
tcpretrans-bpfcc
# 追踪文件打开(比 strace 开销小得多)
opensnoop-bpfcc
# 追踪进程执行
execsnoop-bpfcc
# 磁盘 I/O 延迟分析
biolatency-bpfcc
# DNS 查询追踪
gethostlatency-bpfcc
六、与其他工具对比
- BPFtrace vs strace:BPFtrace 开销极低(内核态执行),strace 开销较大(用户态 ptrace)。strace 更简单,BPFtrace 更强大。
- BPFtrace vs perf:perf 擅长 CPU 采样,BPFtrace 擅长事件追踪。两者互补使用效果最佳。
- BPFtrace vs SystemTap:BPFtrace 更安全(沙箱执行),SystemTap 功能更完整但需要编译内核模块。
总结
BPFtrace 是现代 Linux 性能分析的核心工具,在搬瓦工 VPS 的生产环境中可以安全使用。配合 perf 进行 CPU 分析和 火焰图 进行可视化,形成完整的性能分析工具链。对于快速调试,strace 仍然是最便捷的选择。选购搬瓦工 VPS 请查看 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣,通过 bwh81.net 访问官网。