等待时间归因
常规火焰图统计的是线程在处理器上运行的时间,看不见阻塞。离开处理器的时间归因则把线程处于等待状态的时间按调用栈累计,再画成图,用来回答「线程这段时间到底在等什么」。锁等待、磁盘与网络等待、被抢占,都会在图里呈现出各自的栈形状。
基本信息
| 适用平台 | Linux,需要内核 eBPF 支持与相应权限 |
|---|---|
| 采集对象 | 按调用栈累计的等待时长 |
| 常用参数 | 分隔线程栈与内核栈、输出折叠格式、限定目标进程 |
| 读图口径 | 宽度表示等待时间,而不是处理器占用时间 |
| 配套工具 | 栈转换与渲染脚本,与在处理器上采样的工具链一致 |
典型使用场景
- 线程数已满、处理器却不忙,怀疑大量线程在等待锁。
- 请求超时但处理器占用不高,需要确认阻塞位置。
- 区分网络等待、磁盘等待与调度等待,决定优化方向。
- 与在处理器上采样的图对照,形成完整的性能画像。
- 验证锁粒度调整或连接池扩容后等待是否下降。
生成
生成
offcputime-bpfcc -df 30 > /tmp/offcpu.folded # 采集 30 秒,输出折叠格式
offcputime-bpfcc -p 12345 -df 30 > /tmp/app.folded # 限定进程,减少噪声
./flamegraph.pl /tmp/offcpu.folded > /tmp/offcpu.svg # 渲染成图
./flamegraph.pl --bgcolor=green /tmp/offcpu.folded > /tmp/offcpu.svg # 与在处理器图配色区分
grep -i futex /tmp/offcpu.folded | head # 先在折叠文件里检索等待类型读图与归因
| 图中特征 | 常见等待来源 | 下一步 |
|---|---|---|
| 栈里出现锁相关内核路径 | 锁竞争或临界区过长 | 结合锁分析确认热点锁 |
| 栈落在文件与磁盘路径 | IO 等待 | 看块层延迟分布 |
| 栈落在网络收发路径 | 对端响应慢或带宽受限 | 查连接与重传情况 |
| 栈很短且分散 | 调度等待或抢占 | 看运行队列延迟分布 |
等待时间会随线程数叠加:十个线程各等一秒,图上的总宽度是十秒,而墙钟时间只有一秒;解读时要结合线程规模,不要直接与请求耗时对应。
不限定目标进程时全系统等待都会进入样本,图会变得杂乱难读;排查具体服务时先按进程过滤,再看整机视角。