<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ebpf · XB 现场笔记</title><link>https://www.xbcatm.com/zh/tags/ebpf/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://www.xbcatm.com/zh/tags/ebpf/index.xml" rel="self" type="application/rss+xml"/><item><title>BPF tracepoint 能窥探正在运行的内核</title><link>https://www.xbcatm.com/zh/posts/bpf-tracepoint-perf-profiling/</link><pubDate>Mon, 06 Mar 2028 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/posts/bpf-tracepoint-perf-profiling/</guid><description>借助内核 tracepoint 与 BPF，无需插桩代码或暂停业务负载就能采样、计数事件。</description><content:encoded>&lt;p&gt;BPF 与内核 tracepoint 能在源头观察行为，且占用极小：不加 agent、不重启、不打断正在跑的工作负载。传统剖析意味着装东西、带 flag 重启、或暂停进程——每样都扰动被研究对象，或在生产根本不被允许。BPF 探针挂到跑着的内核上，收走答案就摘掉，工作负载原样归还。&lt;/p&gt;
&lt;p&gt;BPF 给的是日志给不了的答案：哪些 syscall 烧时间，哪些文件卡磁盘，TCP 重传聚在哪，全从主机每个进程实时采样。&amp;ldquo;哪里慢&amp;quot;&amp;ldquo;现在发生什么&amp;rdquo;，对的一行命令一分钟，胜过日志考古一小时。&lt;/p&gt;
&lt;h2 id="不断流地探测"&gt;不断流地探测&lt;/h2&gt;
&lt;p&gt;一个很小的 eBPF 程序挂到某个既有 tracepoint 上，一边累计计数或直方图统计数据，工作负载照常跑。它运行在内核上下文，探针几乎不会成为瓶颈。程序加载前先过验证器——内核检查内存安全与可终止——有 bug 的探针被拒绝，而不是带崩机器。聚合发生在内核 map 里，几百万事件先坍成小直方图再出用户态；常见开销个位数百分比，往往比团队本来就跑着的日志还便宜。&lt;/p&gt;
&lt;p&gt;从问题出发，不从工具出发。&amp;ldquo;哪个进程开文件最多&amp;quot;是一种 trace 形态，&amp;ldquo;按设备看 p99 磁盘延迟&amp;quot;是另一种，bpftrace 一行命令画廊两种都覆盖，不用写 C。优先高级前端——bpftrace、bcc 工具——真需要定制逻辑再碰 raw BPF；故障时写得出的一行，胜过下周才写完的完美程序。&lt;/p&gt;
&lt;h2 id="tracepoint-是更稳定的名字"&gt;tracepoint 是更稳定的名字&lt;/h2&gt;
&lt;p&gt;内核 tracepoint 标记 block I/O、调度、syscall 进出这类事件，名称比裸 kprobe 更不易碎，跨内核升级依旧健壮。kprobe 钉内核函数地址，版本一换就漂；tracepoint 命名内核承诺保持的语义事件，周二补丁重启后同一探针照跑。挂离行为最近的：磁盘问题挂 block，离 CPU 延迟挂调度，&amp;ldquo;谁调什么&amp;quot;挂 syscall。&lt;/p&gt;
&lt;p&gt;猜名字前先列出现有什么——tracepoint 在内核 tracing 接口下枚举着，标准工具都能打印。真没有 tracepoint 覆盖的事件，刻意降级 kprobe 或 uprobe，注释里钉死内核版本，张着眼睛付维护成本。稳定性是光谱：tracepoint 优先，知名 kprobe 其次，裸地址永远别进想保留的东西。&lt;/p&gt;
&lt;h2 id="读直方图而不是开闸放水"&gt;读直方图，而不是开闸放水&lt;/h2&gt;
&lt;p&gt;把嘈杂的事件流聚合成延迟或计数直方图，最先暴露得分偏低的那一档异常，而不是把每个事件都打印出来。先看形状定位头号嫌疑，再往细分钻。一百万 syscall 的逐条 dump，人读不出任何东西；log 刻度延迟直方图一屏展示双峰——快路径对慢的 1%。直方图是诊断，单事件只是确认，直方图指了方向再采样。&lt;/p&gt;
&lt;p&gt;聚合键保持紧：一按进程、一按文件、一按 syscall，一次一维。二维拆分爆炸基数、活埋信号，全参数 dump 把 firehose 从后门请回来。直方图点名嫌疑后，转对该进程或文件单独定向 trace，加时间 bound，拿到确认样本就停。
生产用前先在 staging 把探针跑一遍，确认输出格式和开销都符合预期，再决定采样率。把验证过的 one-liner 收进团队 runbook，下次同类问题直接取用，不用临场现写。
采样结论先在小范围复现一次再推广，避免单次采样的偶然当成规律。
结论写进复盘时附上探针原文，保证别人能原样重跑。&lt;/p&gt;
&lt;p&gt;上线前在预发环境对照业务指标测一轮开销：先记录不挂探针时的请求延迟与 CPU 占用，再挂上同样的聚合探针跑十分钟，对比两者差距。只有确认差距落在个位数百分比以内，才把采样率与过滤条件带到生产；若差距超标，就收紧过滤到单个进程或拉长聚合窗口，直到开销回到可接受范围，再把这组参数连同探针一起收进 runbook。&lt;/p&gt;
&lt;h2 id="坏掉的样子"&gt;坏掉的样子&lt;/h2&gt;
&lt;p&gt;最经典的是挂不上的探针：tracepoint 名错、缺内核头、环境锁死禁 BPF 加载——工具悄悄退出或甩一句神秘 verifier 信息。先验环境（tracepoint 列得出、loader 权限有）再怀疑探针逻辑；BPF 失败多半是环境的，不是逻辑的。容器里记住探针一般要主机级特权，容器运行时默认不给。&lt;/p&gt;
&lt;p&gt;第二种是大规模下的观察者效应：热路径上无过滤探针——10 万 rps 盒子上 trace 每个 syscall——烧掉整核，还扭曲它正在量的东西。永远内核内聚合、尽早过滤到嫌疑、生产探针限时。开销可疑就把采样砍半或收紧过滤，看答案形状稳不稳；便宜地看就变形的测量，从来不可信。&lt;/p&gt;
&lt;h2 id="快速验证"&gt;快速验证&lt;/h2&gt;
&lt;p&gt;确认工具链可用并取第一张直方图：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bpftrace -l &amp;#34;tracepoint:syscalls:*&amp;#34; | head -n 5
bpftrace -e &amp;#39;tracepoint:syscalls:sys_enter_openat { @opens[comm] = count(); }&amp;#39; &amp;amp;
BPF_PID=$!; sleep 10; kill -INT $BPF_PID; wait
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第一条证明 tracepoint 可见，十秒采样按文件打开数给进程排名——每次 BPF 调查的缩微形状。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bpftrace.org/"&gt;bpftrace 内核追踪文档&lt;/a&gt;，bpftrace 官方参考，已核验 2026-06-01。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ebpf.io/what-is-ebpf/"&gt;eBPF 介绍&lt;/a&gt;，eBPF 官方文档，已核验 2026-09-05。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>