Linux bcc 的 funccount / funclatency / biotop 工具生产监控模板

1次阅读

根本原因是默认采样窗口过短且未过滤干扰进程;funclatency直方图大量0因纳秒单位与2倍桶宽不匹配,需用-m切毫秒单位并设-d限定范围。

Linux bcc 的 funccount / funclatency / biotop 工具生产监控模板

funccount 统计函数调用频次时,为什么总看到 0 或数值跳变异常?

根本原因不是工具不准,而是默认采样窗口太短(1 秒),且未排除内核抢占、调度抖动和短生命周期进程干扰。

  • funccount 默认只抓 1 秒内的调用次数,对低频但关键的函数(比如 sys_openat)容易漏统计 —— 改用 -d 5 指定 5 秒持续采样
  • 不加 -P 会混入所有进程调用,包括 kthreaddrcu_gp 等内核线程,导致数据失真 —— 生产环境务必加 -P $(pgrep -f 'your_app')
  • 某些函数(如 tcp_sendmsg)在 TCP fastopen 或零拷贝路径下可能被绕过,单纯看计数不能等价于“业务请求量”
  • 示例:监控某 Java 应用的 sys_read 调用频次:
    funccount -P $(pgrep -f 'java.*order-service') -d 5 'sys_read'

funclatency 测延迟时,直方图输出里为什么大量 bin 显示 0?

不是没延迟,是默认时间单位(纳秒)和桶宽(2 倍增长)不匹配,导致低延迟区间分辨率不足。

  • 默认桶从 1ns 开始,按 2× 增长:1, 2, 4, 8… 直到 1s —— 对微秒级系统调用(如 gettimeofday),前 10 个 bin 全是 0
  • -m 切换为毫秒单位,再配 -D 100(最大 100ms)能看清真实分布:
    funclatency -m -D 100 -P $(pgrep -f 'nginx') 'ngx_http_process_request'
  • 注意:-m-u(微秒)不能共存;-m 下最小桶是 1ms,低于该值的延迟全归入第一桶
  • 如果目标函数调用极快(trace + timestamp 手动算差值,funclatency 不适合亚微秒精度场景

biotop 在容器环境里看不到宿主机磁盘 I/O?

因为 biotop 默认只跟踪当前 cgroup 的 I/O,而容器进程常被移入子 cgroup(如 /kubepods/burstable/podxxx/...),工具找不到对应上下文。

  • 先查目标容器的 cgroup 路径:
    cat /proc/$(pgrep -f 'redis-server')/cgroup | grep blkio

    ,拿到类似 8:blkio:/kubepods/burstable/podabc/redis

  • biotop -C 指定完整路径:
    biotop -C '/kubepods/burstable/podabc/redis' -d 3
  • 若容器使用 io.weight(cgroup v2),biotop 无法识别 —— 此时必须降级到 cgroup v1 模式,或改用 biosnoop + 进程名过滤
  • biotop 不显示网络块设备(如 EBS、Ceph RBD)的底层物理设备名,只显示逻辑名(nvme0n1),需结合 lsblkfindmnt 对齐实际挂载点

三个工具一起用时,为什么 funccount 和 biotop 时间对不上?

它们底层触发机制不同:funccount 用 kprobe,biotop 用 tracepoint,时间戳来源和延迟不可比,强行对齐会误导根因判断。

  • funccount 记录的是函数入口时间,biotop 记录的是 block_rq_issue tracepoint 触发时刻 —— 中间隔着 VFS 层、IO 调度器排队,差值可达毫秒级
  • 不要用 funccount sys_write 的峰值去解释 biotop 的 IOPS 尖峰,前者反映应用层写调用频次,后者反映实际下发到设备的请求数,中间有 page cache、合并、预读等多层缓冲
  • 真正要关联分析时,优先选同一事件源:比如用 trace 'r::ext4_file_write_iter "pid=%d %s", pid, args->buf' -T 同时捕获调用栈和时间戳,再导出比对
  • 生产模板里建议固定采样周期(如统一用 -d 10),但绝不假设各工具输出的时间列可直接相减

最麻烦的其实是 cgroup v2 + 容器 + 多线程混合场景下,funccount -P 可能漏掉 fork 出的子线程,而 biotop -C 又要求精确路径 —— 这时候得先确认 PID 是否稳定、cgroup 是否实时更新,而不是直接怀疑工具坏了。

text=ZqhQzanResources