当前位置: 首页 > news >正文

eBPF性能分析实战

eBPF性能分析实战一、eBPF概述eBPFextended Berkeley Packet Filter是Linux内核的一项革命性技术支持在运行时动态加载程序。1.1 eBPF架构┌─────────────────────────────────────────────────────────────┐ │ 用户空间 │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ bpftool │ │ BCC/CLang │ │ 用户程序 │ │ │ │ 工具链 │ │ 编译器 │ │ │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ ├─────────┼─────────────────┼─────────────────┼─────────────┤ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ Linux 内核 │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ │ │ eBPF 虚拟机 │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ │ │ Map │ │ Program│ │ Verifier│ │ │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ └────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ │ │ tracepoint kprobe kretprobe │ │ │ │ perf_event uprobe raw_tracepoint │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘1.2 eBPF程序类型类型说明用途kprobe内核函数入口探测监控内核函数调用kretprobe内核函数返回探测获取函数返回值uprobe用户函数入口探测监控用户态程序tracepoint静态追踪点稳定的内核追踪perf_event性能事件采样分析二、环境准备2.1 检查内核版本# 检查内核版本需要4.15 uname -r # 检查eBPF支持 cat /proc/sys/kernel/bpf_enabled # 安装依赖 apt-get install -y bpfcc-tools linux-tools-common linux-tools-$(uname -r)2.2 安装BCC工具# Ubuntu/Debian apt-get install -y bcc bcc-tools libbcc-examples # CentOS/RHEL yum install -y bcc bcc-tools # 验证安装 bpftrace -e BEGIN { printf(eBPF works!\n); exit(); }三、eBPF程序开发3.1 使用BCC编写eBPF程序from bcc import BPF # 定义eBPF程序 bpf_text #include uapi/linux/ptrace.h BPF_HASH(counter); TRACEPOINT_PROBE(syscalls, sys_enter_openat) { u64 pid bpf_get_current_pid_tgid() 32; counter.increment(pid); return 0; } # 加载并运行 b BPF(textbpf_text) # 打印结果 while True: try: for k, v in b[counter].items(): print(fPID {k.value}: {v.value} openat calls) b[counter].clear() sleep(1) except KeyboardInterrupt: exit()3.2 使用bpftrace编写脚本#!/usr/bin/env bpftrace # 追踪execve系统调用 tracepoint:syscalls:sys_enter_execve { printf(PID %d called execve: %s\n, pid, str(args-filename)); } # 统计进程系统调用次数 profile:hz:99 { [comm] count(); } END { print(); }3.3 C语言编写eBPF程序#include vmlinux.h #include bpf/bpf_helpers.h struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 10240); __type(key, u64); __type(value, u64); } counter SEC(.maps); SEC(tracepoint/syscalls/sys_enter_openat) int trace_openat(struct trace_event_raw_sys_enter *ctx) { u64 pid bpf_get_current_pid_tgid() 32; u64 *count bpf_map_lookup_elem(counter, pid); if (count) { (*count); } else { u64 init 1; bpf_map_update_elem(counter, pid, init, BPF_ANY); } return 0; } char _license[] SEC(license) GPL;四、性能分析实战4.1 CPU分析# 查看CPU使用率最高的进程 bpftrace -e profile:hz:99 { [comm, pid] count(); } END { sort(); } # 分析内核函数调用 bpftrace -e kprobe:do_sys_open { [func] count(); } # 分析用户态函数 bpftrace -e uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc { [malloc calls] count(); }4.2 内存分析# 追踪内存分配 bpftrace -e kprobe:kmalloc { [size] count(); } # 分析内存泄漏 bpftrace -e kprobe:kmalloc { alloc[pid, comm] sum(args-size); } kretprobe:kfree { free[pid, comm] sum(args-size); } # 查看slab分配 bpftrace -e tracepoint:slab_alloc { [name] count(); }4.3 网络分析# 追踪TCP连接 bpftrace -e tracepoint:tcp:tcp_connect { printf(Connect: %s:%d - %s:%d\n, args-saddr, args-sport, args-daddr, args-dport); } # 分析数据包 bpftrace -e tracepoint:net:netif_receive_skb { [args-name] count(); } # 查看网络延迟 bpftrace -e kprobe:tcp_sendmsg { start[pid] nsecs; } kretprobe:tcp_sendmsg { latency hist(nsecs - start[pid]); delete(start[pid]); }4.4 文件系统分析# 追踪文件打开 bpftrace -e tracepoint:syscalls:sys_enter_openat { [str(args-filename)] count(); } # 分析磁盘I/O bpftrace -e tracepoint:block:block_rq_issue { [rwbs] count(); } # 查看文件读写大小分布 bpftrace -e tracepoint:syscalls:sys_enter_read { read hist(args-count); } tracepoint:syscalls:sys_enter_write { write hist(args-count); }五、高级应用5.1 动态追踪应用启动from bcc import BPF import time bpf_text #include uapi/linux/ptrace.h BPF_PERF_OUTPUT(events); struct event { u32 pid; char comm[16]; char filename[256]; }; TRACEPOINT_PROBE(syscalls, sys_enter_execve) { struct event e {}; e.pid bpf_get_current_pid_tgid() 32; bpf_get_current_comm(e.comm, sizeof(e.comm)); bpf_probe_read_user_str(e.filename, sizeof(e.filename), (void *)args-filename); events.perf_submit(args, e, sizeof(e)); return 0; } b BPF(textbpf_text) def print_event(cpu, data, size): event b[events].event(data) print(fPID {event.pid} ({event.comm.decode()}): execve({event.filename.decode()})) b[events].open_perf_buffer(print_event) while True: b.perf_buffer_poll()5.2 性能计数器#!/usr/bin/env bpftrace profile:hz:99 { cpu[cpu] count(); pid[pid, comm] count(); } tracepoint:sched:sched_switch { switches count(); } END { printf(CPU distribution:\n); print(cpu); printf(\nTop processes:\n); sort(pid, -1); print(pid, 10); printf(\nContext switches: %d\n, switches); }5.3 错误追踪#!/usr/bin/env bpftrace tracepoint:syscalls:sys_exit_openat /args-ret 0/ { errors[-args-ret] count(); } tracepoint:syscalls:sys_exit_socket /args-ret 0/ { socket_errors[-args-ret] count(); } END { printf(Open errors:\n); print(errors); printf(\nSocket errors:\n); print(socket_errors); }六、工具链对比工具语言适用场景优点缺点bpftrace脚本快速原型简单易用功能有限BCCPython/C复杂分析功能强大学习曲线libbpfC生产环境高性能开发复杂七、最佳实践7.1 性能优化建议减少数据收集只收集必要的数据使用哈希表合理使用BPF_MAP_TYPE_HASH批量输出减少用户态和内核态交互避免复杂计算在用户态处理复杂逻辑7.2 安全注意事项权限控制eBPF需要CAP_BPF权限程序验证内核会验证eBPF程序安全性资源限制设置合理的内存和指令限制7.3 调试技巧# 查看eBPF程序 bpftool prog list # 查看eBPF map bpftool map list # 查看tracepoint cat /sys/kernel/debug/tracing/available_events # 查看kprobe可用函数 cat /proc/kallsyms | head -20八、总结eBPF是性能分析的利器无侵入式无需修改内核或应用代码高性能在内核态执行低开销灵活强大支持多种追踪方式安全可靠内核验证确保安全通过eBPF可以深入了解系统内部运行机制定位性能瓶颈。
http://www.rkmt.cn/news/1371788.html

相关文章:

  • Prometheus自定义指标实战
  • Grafana告警规则配置实战
  • Taotoken API密钥的精细化管理与访问审计日志在安全运维中的价值
  • 卒中治疗个性化效果评估:17种因果机器学习模型实战比较
  • 2026年5月北海银海地区黄金回收白银铂金回收门店推荐TOP1 地址及联系方式 - 检测回收中心
  • 终极指南:5分钟快速上手Eclipse Ditto数字孪生平台
  • NightX Client:打造终极Minecraft 1.8.9游戏体验的完整指南
  • 2026校招人才整体素质洞察
  • 2026年5月北京昌平地区黄金回收白银铂金回收门店推荐TOP1 地址及联系方式 - 检测回收中心
  • 使用Taotoken CLI工具一键配置多开发环境与工具密钥
  • AI Agent在DevOps中的应用:自主监控、根因分析与故障修复
  • 5分钟掌握unluac:Lua字节码反编译完整指南
  • 高级内核模式硬件信息欺骗工具:深度解析Windows驱动级设备指纹伪装技术
  • 新手注册Taotoken后快速获取并测试首个API Key的指南
  • 手把手教你:openEuler 22.03启动报错‘Failed to execute /sbin/init’的完整修复流程(附专用镜像下载)
  • AI Agent Harness Engineering 模型压缩技术:让智能体在资源受限设备上高效运行
  • Kubernetes云原生数据库部署方案:构建高可用数据库集群
  • Kubernetes事件驱动架构实践:构建响应式微服务系统
  • 2026年多普勒流量计厂家排行榜:国产品牌技术突围与市场格局深度解析 - 水质仪表品牌排行榜
  • 零基础玩转AI斗地主:DouZero_For_HappyDouDiZhu快速上手实战指南
  • 如何构建高效笔记系统:解锁OneNote智能编辑新体验
  • 7、IntelliJ IDEA 之代码模板
  • QModMaster:3分钟掌握开源ModBus调试工具的终极使用指南
  • 告别版本冲突!详解CentOS 7/8下Chrome与Chromedriver的版本匹配玄学
  • 不止于安装:银河麒麟Kylin V10 SP2服务器版上手后必做的几件事
  • 云存储与CDN
  • 2026宜昌净水器排行榜,口碑实力双优推荐 - 资讯纵览
  • 机器学习势函数在暗物质探测中的应用:计算晶体缺陷存储能
  • Label Studio数据标注工具:从安装到实战的完整指南
  • 北京伸缩门安装维修难题?揭秘真正靠谱的几家选择! - 资讯纵览