阻塞时间归因
按调用栈累计线程离开处理器的时间,与在处理器上采样的工具形成互补:前者回答「等待花在哪里」,后者回答「计算花在哪里」。输出可以选择折叠格式,直接生成离处理器火焰图。锁等待、IO 等待与调度等待在这里都会留下不同形状的栈。
基本信息
| 适用平台 | Linux,需要内核 eBPF 支持与较高权限 |
|---|---|
| 关键参数 | 分隔线程栈与内核栈、输出折叠格式、限定目标进程 |
| 输出形态 | 按栈聚合的阻塞时长,或折叠格式 |
| 读图口径 | 数值是等待时间,不是处理器时间 |
| 配套工具 | 栈折叠与火焰图渲染脚本 |
典型使用场景
- 线程池已满但处理器空闲,确认线程是否都卡在等待上。
- 定位锁等待的调用路径,为缩小临界区提供依据。
- 区分磁盘等待、网络等待与调度等待,决定优化方向。
- 生成离处理器火焰图,与在处理器采样图对照阅读。
- 验证扩容连接池、调整锁粒度之后等待是否下降。
归因推进
归因推进
offcputime-bpfcc -df 30 # 采集 30 秒,输出折叠格式
offcputime-bpfcc -p 12345 -df 30 # 限定进程,减少噪声
offcputime-bpfcc -p 12345 -df 30 > off.folded
./flamegraph.pl off.folded > off.svg # 折叠栈生成火焰图
grep -i futex off.folded | head # 先在文本里检索锁等待
grep -c 'io_schedule\|blk' off.folded # 统计块层相关等待条数输出与用途
| 输出内容 | 含义 | 用途 |
|---|---|---|
| 调用栈 | 发生等待的代码路径 | 定点到具体函数 |
| 等待时长 | 该栈累计阻塞时间 | 判断主要矛盾 |
| 线程标识 | 等待所属线程 | 区分不同工作线程 |
| 折叠格式 | 一行一栈带计数 | 直接渲染火焰图 |
等待时间会随线程数叠加:多个线程各自等待的时间会累加,与请求的墙钟耗时不是一个口径,解读时要结合并发规模。
把阻塞时间等同于问题影响面会得出错误优先级:某个栈累计等待很长,但相关业务量很小,实际影响可能远低于一个等待时间较短却高频的路径。