当前位置:首页>Linux>Linux 系统性能基础设施:工具背后的数据源关系

Linux 系统性能基础设施:工具背后的数据源关系

  • 2026-06-27 18:45:26
Linux 系统性能基础设施:工具背后的数据源关系

术语使用申明

文中多处出现 BPF、eBPF 混用表述,统一说明如下:

cBPF 指代经典伯克利包过滤,是早期专为网络数据包过滤设计的实现;eBPF 即扩展伯克利包过滤,是现代 Linux 内核通用可编程执行框架;上下文无歧义时,会简写为 BPF 统称整套技术体系,不再刻意区分 cBPF 与 eBPF;涉及历史演进、功能差异、代码类型时,将严格区分 cBPF、eBPF,避免概念混淆。

引言:为什么同类性能工具多达十余种?

在 Linux 问题排查与性能观测中,同一类场景往往对应多款工具:磁盘 I/O 分析有 iostatiotopblktracebiolatency;网络观测可选择 sstcpdumptcpretranssar。很多人疑惑:功能相近的工具为何需要重复存在?

答案并非功能冗余,而是底层数据采集链路与计算位置截然不同。

传统观测工具普遍采用「内核原始数据透出 + 用户态二次计算」模式:iostat 读取 /proc 虚拟文件系统的全局计数器,ss 基于 netlink 套接字拉取内核套接字信息,tcpdump 依靠内核抓包机制获取原始报文。数据原样输出后,过滤、统计、分析全部在用户态完成。

以 eBPF 实现的 biolatencytcpretrans 等工具则采用全新架构:将自定义逻辑注入内核,在事件产生的瞬间完成过滤、聚合、延迟统计,仅把加工后的轻量化结果导出至用户态。

同一个硬件/内核事件,经由不同链路采集后,数据粒度、时间精度、信息完整性都会产生明显差异。一款工具能做什么、不能做什么,上限由其数据通路决定。

本文将拆解 Linux 性能数据从「内核事件产生 → 内核预处理 → 数据导出 → 用户态消费」的完整分层体系,帮你理解各类工具的底层逻辑,实现精准选型。


一、Linux 性能观测四层体系


第一层:事件源层

所有性能数据的起点,分两类:

  • 硬件事件:CPU PMU 计数器溢出中断、MSR 寄存器、网卡 / 磁盘硬件事件;

  • 内核软件事件:进程调度、I/O 读写、内存分配、系统调用等。

Tracepoint、kprobe 是埋设在内核代码关键路径上的触发接口,是第一层与第二层的边界——事件在第一层发生,注册的处理逻辑在第二层执行。

特点:纳秒级触发,要求回调开销极低。


第二层:内核计算层

事件触发后,注册的处理程序在内核上下文同步执行,是传统工具与 eBPF 工具的核心分水岭:

  • 传统模式(perf_events 内核侧、ftrace):以计数累加、原始事件入队为主,处理逻辑固定,不可编程;

  • eBPF 模式:执行用户编写的字节码(经 JIT 编译为本地机器码),可在数据离开内核前完成过滤、聚合、调用栈采集、流量分类等复杂逻辑,在内核端完成降噪与精简。

    关于 eBPF 的跨层说明:eBPF 并不只属于本层。XDP 程序挂载在网卡驱动的 NAPI poll 路径,TC eBPF 在协议栈入口,两者的执行时机比多数内核软件事件更早,更靠近第一层。准确地说,eBPF 是一个纵向贯穿多层的可编程框架,第二层是其最主要、最典型的执行场景。


    第三层:数据导出层(按数据形态 & 通道大类归类)

    第二层处理结果透出到用户态的通道,定义数据格式与访问接口:

    类型
    接口
    说明
    聚合计数
    /proc、/sys
    虚拟文件系统,轮询读取
    原始事件流
    perf_events ring buffer、ftrace ring buffer
    内核写入,用户态 mmap 消费
    eBPF 结果出口
    eBPF Map、eBPF ring buffer
    Map 存聚合结果,ring buffer 传事件流;计算本身发生在第二层
    通知接口
    netlink socket
    异步推送

    异步推送:基于事件驱动模型,用户态进程提前向内核订阅指定事件,内核在事件发生后主动将数据推送至用户态,进程无需循环轮询查询。该模式实时性更强、CPU 开销更低,是 netlink 接口最核心的特性,广泛用于网络状态、系统审计、设备热插拔等实时监控场景。


    第四层:用户态消费层

    读取第三层数据,完成格式化、分析、可视化与告警:

    类别
    工具示例
    通用系统指标
    top、iostatvmstatsar
    内核追踪
    perf、ftracetrace-cmd
    eBPF 工具链
    bcc、bpftracelibbpf
    监控采集
    Prometheus node_exporter、collectd
    可视化
    Grafana、Flame Graph

    工具能力上限由它所消费的数据源决定——无论逻辑多精妙,都无法获得数据源里没有的信息。


    二、五类内核事件源


    与四层体系的对应关系

    本章聚焦第一层(事件源层),说明性能数据从哪里产生、由哪种机制触发。第三章将对应介绍第三层(数据导出层)的六种机制 —— 同一套数据,两章分别从 "产生" 和 "导出" 两个维度切入。

    按数据产生的形态,五类事件源可分为两大组别:

    • 累积计数型:数据为持续累加的统计值,无单次事件详情,需轮询差分计算速率,包括「内核软件计数器」与「MSR 寄存器」;

    • 事件触发型:数据为瞬时触发的单次事件,带精确时间戳与上下文,包括「Tracepoint」「kprobe/uprobe」「硬件 PMU 计数器」。

      下表给出五类事件源在四层体系中的完整定位,也是两章内容的衔接索引:

      *------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| 事件源                  | 第一层:事件产生                          | 第二层:内核计算                  | 第三层:导出接口                              | 第四层:用户态工具        |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| 内核软件计数器           | 调度/I/O/内存累计计数                     | 无                              | /proc、/sys、cgroup(机制一)                 | iostat、vmstat、top       |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| Tracepoint             | 第一/二层边界触发点                        | ftrace/perf/eBPF 回调           | ftrace RB(机制三)                            | perf、trace-cmd           ||                        |                                          |                                | perf RB(机制二)                              | bcc、bpftrace             ||                        |                                          |                                | eBPF Map(机制五)                             |                           |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| kprobe / uprobe        | 第一/二层边界触发点                        | 同上                            | perf RB(机制二)                              | perf probe                ||                        |                                          |                                | eBPF Map(机制五)                             | bcc、bpftrace             |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| 硬件 PMU               | PMU硬件计数器                              | perf_events采样处理             | perf RB(机制二)                              | perf、bcc profile         |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+| MSR(x86)             | MSR硬件寄存器                              | 无                             | /dev/cpu/*/msr(机制六)                      | turbostat、perf stat      |+------------------------+------------------------------------------+--------------------------------+----------------------------------------------+---------------------------+

      2.1 累积计数型事件源

      事件源一:内核软件计数器

      内核在执行关键路径时,自动维护一系列全局和 per-CPU 的累积计数器,无需任何激活操作,始终在运行。这是性能数据中最古老、开销最低的产生方式。

      在四层体系中的位置:计数器更新本身属于第一层——调度器在上下文切换时更新 CPU 时间计数,块层在 I/O 完成时更新吞吐量计数,内存子系统在缺页时更新缺页计数。这些计数器通过 /proc/sys 和 cgroup 统计文件导出到用户态,后者属于第三层,详见第三章机制一。本节只说明内核跟踪了哪些数据,以及这类计数器的能力边界。

      内核跟踪的代表性计数器

      • CPU 调度(对应 /proc/stat:调度器在每次上下文切换时,按 CPU 核累积记录 user、nice、system、idle、iowait、irq、softirq、steal 时间。topvmstatmpstat 的 CPU 数据均来自这里。

      • 虚拟内存(对应 /proc/meminfo/proc/vmstat:内存子系统分别维护两类数据——/proc/meminfo 是当前用量快照(MemTotal、MemFree、Cached 等约 50 个字段);/proc/vmstat 是事件发生次数(pgfault 缺页次数、pswpin/pswpout swap 换入换出量、nr_dirty 脏页数等)。两者侧重不同,分析内存压力时需要对照使用。

      • 块设备 I/O(对应 /proc/diskstats/sys/block/*/stat:块层在每次 I/O 完成时,按设备累积记录读/写次数、扇区数、等待时间、队列深度等。iostat 每隔 N 秒读两次做差分,换算成速率。/sys/block/*/stat 比 /proc/diskstats 粒度更细,可区分不同队列。

      • 网络(对应 /proc/net/dev:网络子系统按接口累积记录收发包数、字节数、错误数、丢包数。ifconfigip -s linksar -n DEV 的数据来源。

      • 进程级 I/O(对应 /proc/PID/io:内核为每个进程独立累积记录读写字节数和系统调用次数。有局限性——进程退出后数据消失,这时需通过 Taskstats netlink 接口获取。

      • slab 缓存(对应 /proc/slabinfo:内存分配器按对象类型记录缓存数量和大小,slabtop 读取这个文件。

      • socket 状态(对应 /proc/net/tcp 等):网络子系统维护所有活跃 TCP/UDP socket 的状态表,netstat 解析这些文本文件,但 socket 数量极多时性能较差;ss 通过 netlink 直接查询内核,速度更快,推荐替代 netstat

      PSI(压力停顿信息)

      Linux 4.20 引入的 PSI(Pressure Stall Information)是一类特殊的软件计数器,通过 /proc/pressure/ 导出,是目前最准确的系统压力指标。与上述利用率计数器不同,PSI 直接测量"有任务在等待资源"的时间比例:

      级别
      含义
      适用维度
      some
      部分任务在等待,CPU 上仍有其他任务在运行
      CPU、内存、I/O
      full
      所有任务都在等待,资源完全停顿
      内存、I/O(CPU 无此级别)

      三个维度各提供 10s、60s、300s 三个滑动窗口均值。Facebook 大规模部署的 oomd、systemd 资源控制均以 PSI 为核心信号,是比 %iowait 或 %util 更直接的压力度量。

      cgroup 分组计数器(v1 与 v2 有区别)

      cgroup 子系统在内核中为每个控制组独立维护一套资源计数,是容器化环境按容器维度观测资源的数据基础。v1 和 v2 的计数器路径和格式不同:

      cgroup v1(旧的多层级结构)

      • CPU:/sys/fs/cgroup/cpu/<group>/cpu.stat
      • 内存:/sys/fs/cgroup/memory/<group>/memory.stat
      • 块 I/O:同时提供原生 I/O 统计 blkio.io_service_bytes(实际 I/O 量)和限流统计 blkio.throttle.io_service_bytes(受限流策略影响的 I/O),两者含义不同,没有统一的 io.stat

      cgroup v2(统一层级,现代发行版默认):所有控制器集中在 /sys/fs/cgroup/<group>/ 下,重要文件包括 cpu.statmemory.statio.stat(v2 专有,统一了 v1 的多个分散文件)。

      主流发行版(Fedora 31+、Ubuntu 21.10+、RHEL 9+)和 Kubernetes 1.25+ 均已默认采用 cgroup v2。cadvisor、docker stats 等工具会自动适配所在系统的 cgroup 版本。

      这类事件源的能力边界

      内核软件计数器的核心特征是:数据是聚合的(累积计数而非单次事件),是定期轮询的(工具需差分计算速率),是预先定义的(内核开发者决定暴露哪些字段)。无法获取单次事件的时间戳、调用栈和上下文——这是它与后三类插桩型事件源的根本差异,也是为什么同一个问题需要多种工具的核心原因之一。


      事件源二:MSR 寄存器(x86/x86-64 专有)

      架构限制:本事件源为 x86/x86-64 专有。ARM64 不存在 MSR 机制,RAPL 能耗统计不可用,turbostat 不支持 ARM64。ARM64 的能耗和频率信息需通过 hwmon(/sys/class/hwmon/)、ACPI CPPC 或芯片厂商专有接口获取,无统一标准。

      CPU 内部的 Model Specific Registers 存储了 PMU 无法直接暴露的硬件状态:RAPL 能耗计数器(Running Average Power Limit)、当前频率、温度传感器等。这是第一层的硬件数据来源。

      在四层体系中的位置在四层体系中的位置:MSR 寄存器是第一层的硬件状态;/dev/cpu/N/msr 设备文件是第三层的导出接口(详见第三章机制三);读取工具属于第四层。与 PMU 不同,MSR 没有第二层的内核侧预处理,用户态工具直接读取原始寄存器值。MSR 同时出现在本章(第一层:数据来源)和第三章(第三层:访问接口),是因为它的数据产生和接口访问都有独立讨论价值。

      实际使用中的常见限制:访问需要 root 权限;主流云虚拟机出于安全隔离通常会屏蔽 MSR 访问(/dev/cpu/*/msr 不可读或返回全零);RAPL 能耗统计在 Intel 平台支持最完整,AMD 从 Zen 架构起提供部分支持,但字段和精度与 Intel 有差异。

      典型使用工具

      • turbostat:显示每个 CPU 核的实时频率、功耗、温度、C-state 停留时间,是分析 CPU 频率缩放和热量限制(thermal throttling)问题的核心工具;

      • perf stat:能耗统计(-e power/energy-pkg/等事件)。

        在分析功耗相关的性能问题(如 CPU 因温度限制而降频、服务器节能策略导致的延迟抖动)时,这个事件源是不可替代的。


        2.2 事件触发型事件源

        事件源三:Tracepoint(静态内核插桩)

        Tracepoint 是内核开发者在代码中主动放置的静态观测点,通过 TRACE_EVENT 宏定义,存在于调度器、内存管理、文件系统、网络协议栈等核心子系统的关键位置。

        在四层体系中的位置:Tracepoint 的触发点是第一层与第二层的边界——事件在第一层发生,注册的处理回调(ftrace、perf_events、eBPF 程序)在第二层执行,结果写入 ring buffer 或 eBPF Map 属于第三层。

        未激活时,Tracepoint 是一条 nop 指令,开销极低(纳秒级)。激活后通过 jump label 机制替换成 jmp,跳转到追踪回调。

        一个容易被忽视的关键设计:Tracepoint 是事件生产者,ftrace ring buffer 和 perf_events 是两条独立的消费渠道,接在同一个事件源上。

        perf record -e sched:sched_switch
        trace-cmd record -e sched:sched_switch

        追踪的是完全相同的内核 Tracepoint,只是数据分别写入 perf ring buffer 和 ftrace ring buffer。工具可以同时注册,同一个 Tracepoint 被触发时,两个 ring buffer 都会收到数据。eBPF 程序也可以 attach 到 Tracepoint 上,三种消费方式可以并存。

        所有可用的 Tracepoint 可通过 /sys/kernel/debug/tracing/events/ 目录查看。重要分类如下:

        • sched 子系统sched_switch(上下文切换)、sched_wakeup(进程被唤醒)、sched_migrate_task(进程跨 CPU 迁移)。这三个 Tracepoint 是调度延迟分析的数据基础,runqlat 工具就是在 sched_wakeup 和 sched_switch 上计算等待时间差。

        • block 子系统block_rq_insert(I/O 请求进入队列)、block_rq_issue(I/O 请求发往驱动)、block_rq_complete(I/O 请求完成)。三者配合使用,可区分队列等待时间(insert 到 issue)和设备处理时间(issue 到 complete)。biolatency 工具的数据来源正是这里。

        • syscalls 子系统sys_enter_xxx 和 sys_exit_xxx,覆盖所有系统调用的进入和退出,是追踪任意系统调用延迟的最稳定接口。

        • net/skb 子系统:数据包在网络栈内的流转事件,包括 skb_kfree_skb(丢包点,带丢包原因)、napi_gro_receive_entry 等,是网络丢包分析的重要数据源。

        • irq 子系统:硬中断和软中断的进入/退出事件,用于分析中断处理延迟。

        • lock 子系统:内核锁竞争事件(lock_acquirelock_releaselock_contended),是 perf lock 工具的数据源。

        Tracepoint 的核心价值是稳定性:内核开发者承诺一旦加入就不会以不兼容的方式变更(ABI 稳定性),因此基于 Tracepoint 编写的工具可以在不同内核版本之间稳定工作。而基于 kprobe 追踪内核函数的工具在内核版本升级后可能需要修改。


        事件源四:kprobe / uprobe(动态插桩)

        kprobe 可以在内核任意函数的入口或返回处动态插入观测点,不需要内核预先埋点。

        在四层体系中的位置:与 Tracepoint 相同——触发点在第一/二层边界,回调执行在第二层,数据出口在第三层。与 Tracepoint 的区别在于:kprobe 是动态的、覆盖范围更广、但稳定性更低。

        在 x86/x86-64 上,其基础机制是将目标函数的第一个字节替换成 int3(软件断点,0xCC);内核会同时备份目标函数前若干字节的原始指令,防止 int3 破坏跨字节的指令边界。触发时调用注册的处理函数。在 ARM64 上则使用 BRK 指令完成相同的拦截。此外,内核还支持 jump optimization:在条件允许时,将 int3 升级为直接的 5 字节 JMP 指令(仅 x86),减少软件中断路径的开销。uprobe 对用户态程序做同样的事情。

        kprobe 的覆盖范围是 Tracepoint 无法比拟的——内核里有数万个函数,Tracepoint 只覆盖了其中数百个关键位置。需要追踪 Tracepoint 没有覆盖的内核行为时(比如追踪某个特定的内存分配路径、追踪某个驱动函数),kprobe 是唯一选择。

        代价是不稳定性:内核函数是内部实现细节,随时可能在版本之间改名、参数变化、被内联而消失。基于 kprobe 追踪的工具需要随内核版本维护。

        kprobe 和 uprobe 事件也可以注册到 perf_events 子系统(通过 perf probe 命令动态添加)或由 eBPF 程序直接 attach,两条消费路径同样并存。

        USDT(User Statically Defined Tracing)是在 Linux 上基于 uprobe 实现的用户态静态追踪规范:应用程序开发者在源码中主动埋设静态观测点,通过 semaphore 机制保证未激活时完全零开销,且不受函数内联、版本改名的影响,稳定性远优于普通 uprobe。MySQL、PostgreSQL、Node.js、Python 等应用内置了大量 USDT 探针,是应用层追踪的最优数据源。


        事件源五:硬件 PMU 计数器

        CPU 内部的 PMU(Performance Monitoring Unit)是性能计数器的硬件实现,直接在硬件层面计数各种微架构事件,不需要任何软件插桩。

        在四层体系中的位置:PMU 硬件计数器本身属于第一层(事件源层);perf_events 内核侧的采样与缓冲属于第二/三层;perf 命令行工具属于第四层。

        固定计数器(总是可用):总指令数(instructions retired)、总时钟周期数(CPU cycles)、参考时钟周期数(不受频率缩放影响)。从这三个计数器可以计算 IPC(每时钟周期指令数),是判断 CPU 微架构效率的核心指标。

        可编程计数器(型号相关):末级缓存缺失(LLC-misses)、分支预测失败(branch-misses)、TLB 缺失(dTLB-load-misses)等。具体支持的事件因 CPU 厂商和型号而异。

        PMU 的使用有两种模式:

        • 计数模式:统计总量,适合计算 IPC、缓存命中率等聚合指标;

        • 采样模式:每 N 次事件采样一次当前 PC 和调用栈,适合生成硬件事件火焰图,定位 LLC 缺失最严重的代码路径。

          PMU 数据通过 perf_events 子系统导出给用户态。eBPF 程序也可以 attach 到 PMU 采样事件上(BPF_PROG_TYPE_PERF_EVENT 程序类型),在每次采样时在内核态执行自定义逻辑——这正是 BCC profile 工具实现 On-CPU profiling 的机制基础。

          关于 BCC profile 工具的采样机制profile 默认以 PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_CLOCK(软件时钟事件)触发,并非硬件 PMU 溢出。软件时钟在所有架构上均可用,且不占用有限的 PMU 硬件计数器槽位。perf record -e cycles 才是使用硬件 CPU cycles 计数器的 PMU 采样。两者的采样精度和适用场景有区别,不应混淆。

          关于 99Hz 的选择:频率选择 99 而非 100,是为了避免与内核定时器中断产生相位锁定(resonance)。内核定时器频率(CONFIG_HZ)常见值为 100、250、1000,若采样频率与其完全对齐,采样会反复落在相同代码位置(如 do_timer()),导致火焰图严重失真。99 是行业惯例;同理,也有使用 249Hz、499Hz 等与常见 CONFIG_HZ 值互质的频率,出于完全相同的考量。

          x86_64 与 ARM64 的差异:PMU 事件名称和编码在两个架构上完全不同。x86_64 使用 Intel/AMD 格式(如 cyclesLLC-load-missesr4f2e),ARM64 使用 PMUv3 标准格式(如 armv8_pmuv3_0/cpu_cycles/armv8_pmuv3_0/l2d_cache_refill/)。perf list 的输出在两个平台上差异显著,跨平台编写 perf 脚本时须参照目标平台的事件名。Tracepoint、kprobe 类事件名与架构无关,两平台一致。


          三、内核数据导出的六种机制


          对应第一层的两类数据形态,六种导出机制可分为两大组别:


            3.1 状态查询类通道
            • 状态查询类通道:面向累积计数型数据,以同步读取、轮询获取为主,包括虚拟文件系统、netlink socket、MSR 寄存器接口;

            • 事件流类通道:面向事件触发型数据,以环形缓冲区、流式传输为主,包括 perf_events 子系统、ftrace ring buffer、eBPF Maps 和 ring buffer。

            机制一:虚拟文件系统(/proc/sys

            最古老、最通用的导出机制。内核维护内存中的数据结构,/proc 和 /sys 把这些结构以虚拟文件的形式呈现。读取这些文件触发内核的读处理函数,把数据序列化成文本返回给用户态。

            优点:接口极其简单,任何语言、任何工具都能访问;不需要特殊权限(大部分文件对所有用户可读);数据始终可用,没有缓冲区满的问题。

            缺点:数据是聚合的历史累积,没有单次事件的详细信息;轮询开销不低(文本解析、频繁读文件);内容由内核开发者预先定义,不能自定义要看哪些数据。

            适用工具topvmstatiostatnetstatfreesardstat 等所有传统命令行工具,以及大多数监控系统的数据采集 agent(Node Exporter、Prometheus 等)。cgroup 统计(cadvisor、docker stats)和 PSI 监控也走这条路。


            机制二:netlink socket

            netlink 是内核和用户态之间专为网络子系统设计的通信机制,支持双向通信(用户态可以查询内核,内核也可以主动通知用户态)。

            ss 命令:ss使用 netlink 获取 socket 信息,比 netstat 读取 /proc/net/tcp 快得多(避免了文本解析,且 netlink 支持按条件过滤,不需要把所有 socket 信息都传到用户态)。ip 命令、iproute2 工具集通过 netlink 查询和配置路由、地址、接口等。

            Taskstats:这是 netlink 在性能领域另一个重要但常被忽视的用途。Taskstats 是内核通过 netlink 导出进程级别任务统计数据的专用协议,提供比/proc/PID/io更完整的进程 I/O 统计——特别是对已退出进程的计,/proc在进程退出后就看不到数据了,而 Taskstats 可以在进程退出时捕获完整统计。iotop主要通过 Taskstats netlink 接口(而非/proc/PID/io)获取进程级 I/O 数据,atop等 accounting 工具也依赖这个接口。

            网络事件通知:当网络接口状态变化(link up/down)、路由变化时,内核通过 netlink 主动通知感兴趣的用户态进程(NetworkManager、systemd-networkd 等监听这些通知)。


            机制三:MSR 寄存器接口

            架构限制:本机制为 x86/x86-64 专有。 ARM64 平台不存在 /dev/cpu/*/msr 接口,RAPL 能耗统计不可用,turbostat 不支持 ARM64。ARM64 的能耗和频率信息需通过 hwmon(/sys/class/hwmon/)、ACPI CPPC、或芯片厂商提供的专有接口获取,无统一标准。

            通过 /dev/cpu/N/msr 设备文件直接读写 CPU 的 Model Specific Registers,访问 PMU 无法直接暴露的硬件信息:RAPL 能耗计数器、当前频率、温度等。需要 root 权限,数据格式与 CPU 型号强绑定。

            实际使用中的常见限制:主流云虚拟机出于安全隔离通常会屏蔽 MSR 访问(/dev/cpu/*/msr 不可读或返回全零);RAPL 能耗统计在 Intel 平台支持最完整,AMD 从 Zen 架构起提供部分支持,但字段和精度与 Intel 有差异。

            turbostat 是这个接口最典型的消费者,能展示每个 CPU 核的实时频率、功耗、温度、C-state 停留时间,是分析 CPU 频率缩放和热量限制(thermal throttling)问题的核心工具。perf stat 的能耗事件(-e power/energy-pkg/)在底层同样依赖 RAPL MSR。


            3.2 事件流类通道

            机制四:perf_events 子系统

            perf_events 是 Linux 2.6.31 引入的统一性能监控接口,通过 perf_event_open() 系统调用访问。它的核心价值在于提供了一个统一的事件订阅框架,把多种异构的事件源(PMU 硬件计数器、Tracepoint、kprobe、uprobe)统一成同一种接口:打开一个 perf_event fd,内核把采样数据写入 mmap 的环形缓冲区,用户态从缓冲区读取。

            perf_events 是一个多消费者的框架,以下几类工具都通过它访问事件:

            perf 命令行工具:直接使用 perf_event_open(),数据写入 perf.data 文件后离线分析,或实时展示统计数据。

            eBPF 程序BPF_PROG_TYPE_PERF_EVENT 类型的 BPF 程序可以 attach 到任意 perf_event 上,在事件触发时执行自定义的内核态逻辑。BCC profile(On-CPU profiling)就是这样工作的:用 perf_events 设置 99Hz 的软件时钟事件,每次触发 BPF 程序采集调用栈并更新 Map。eBPF 在这个场景里是 perf_events 的消费者,而不是与 perf_events 并列的独立机制。

            BPF_MAP_TYPE_PERF_EVENT_ARRAY:这是 eBPF ring buffer 出现(5.8+)之前,BPF 程序把事件数据传给用户态的主要方式——BPF 程序把数据写入 per-CPU 的 perf ring buffer,用户态通过 perf_events 接口读取,顺序不保证,需要为每个 CPU 分别读取。ring buffer 是在此基础上更高效的替代方案(全局共享、保序、支持两阶段提交),但 PERF_EVENT_ARRAY 仍然广泛存在于旧的 BCC 工具里。

            x86_64 与 ARM64 的差异:PMU 硬件事件名称和编码在两个架构上完全不同。x86_64 使用 Intel/AMD 的事件名(如 cyclesLLC-load-missesr4f2e),ARM64 使用 PMUv3 标准事件(如 armv8_pmuv3_0/cpu_cycles/armv8_pmuv3_0/l2d_cache_refill/)。perf list 的输出在两个平台上差异显著,跨平台编写 perf 脚本时必须参照目标平台的事件名。Tracepoint、kprobe、uprobe 类事件名称与架构无关,在两个平台上保持一致。


            机制五:ftrace ring buffer

            ftrace 是内核内置的追踪框架,通过 /sys/kernel/debug/tracing/ 目录下的文件接口控制。它维护一个每 CPU 的环形缓冲区,内核的追踪事件直接写入这个缓冲区,用户态通过读取 trace 文件获取数据。

            ftrace ring buffer 和 perf_events ring buffer 都可以消费 Tracepoint 事件,两者是同一事件源的两个订阅渠道,可以并存,不冲突。选择哪个渠道取决于使用工具:trace-cmd 用 ftrace 渠道,perf 用 perf_events 渠道,eBPF 程序两个渠道都可以用。

            ftrace 的独特功能是 function tracer 和 function_graph tracer:可以追踪内核函数的调用顺序和执行时间,直观地看到内核代码的执行路径(类似程序员熟悉的调用树)。这是 perf 和 BPF 都无法直接提供的能力。

            ftrace 的主要用途

            • 函数调用追踪:追踪某个内核子系统的函数调用顺序和时序;

            • 延迟测量:irqsoff tracer(中断被禁用的时间)、preemptoff tracer(抢占被禁用的时间)、wakeup tracer(最高优先级进程的唤醒延迟)——这类 latency tracer 是低延迟和实时系统问题诊断的专用工具;

            • 事件记录:Tracepoint 事件写入 ftrace ring buffer,通过文本格式读取。

              值得注意的是,perf ftrace 子命令可以直接调用 ftrace 的 function tracer 能力,两者的边界在这里有交叉。

              x86_64与ARM64 的差异:function tracer 的底层插桩机制在两个架构上实现不同。x86_64 使用 fentry 方案——编译器在每个函数入口插入 5 字节 call __fentry__,未激活时替换为 5 字节 NOP,激活时直接原地 patch 回 call 指令,切换开销极低。ARM64 使用 -fpatchable-function-entry=2 方案——编译器在每个函数入口处插入两条 NOP 指令(函数符号指向第一条 NOP,共 8 字节),激活时将第一条 NOP patch 为 BL 跳转至 ftrace trampoline,第二条 NOP 保留或用于 FTRACE_WITH_REGS、live patch 等扩展功能。由于 ARM64 指令定长(4 字节),patch 操作天然对齐;两个独立指令槽位(共 8 字节)比 x86_64 的单个 5 字节槽位提供了更多扩展空间。

              使用 ftrace ring buffer 的工具:trace-cmd(ftrace 的命令行前端)、kernelshark(trace-cmd 的 GUI)。


              机制六:eBPF Maps 和 ring buffer

              BPF Map 是驻留在内核中的数据结构,BPF 程序通过 helper 函数读写,用户态通过文件描述符和 bpf() 系统调用访问。这是 eBPF 程序向用户态输出数据的核心接口——BPF 程序在内核态完成计算后,把结果写入 Map,用户态定期或按需读取,两侧通过同一块内核内存通信。

              聚合结果的导出——Hash / Array Map:适合在内核态累积计算结果再一次性读取的场景。BPF 程序以调用栈、PID、设备号等为 key,在 Map 里做计数或求和;用户态程序定期遍历整张 Map,拿到已经聚合好的统计表,不需要处理原始事件流。biolatencyrunqlat 等工具都用这种模式。

              事件流的导出——两种 ring buffer

                BPF_MAP_TYPE_PERF_EVENT_ARRAY(旧方式):每个 CPU 独立一块 perf ring buffer,BPF 程序调用bpf_perf_event_output()写入,用户态通过 perf_events 接口按 CPU 分别轮询读取。事件全局顺序无法保证,且内存按 CPU 数量线性增长。

                BPF_MAP_TYPE_RINGBUF(5.8+ 新方式):单一全局共享缓冲区,所有 CPU 的 BPF 程序竞争写入同一块内存,事件顺序有保证。写入分两步:reserve预留空间(此时用户态不可见),填充数据后commit提交,失败则discard,避免写入一半的脏数据被用户态读到。支持epoll,用户态可以事件驱动地读取,无需忙轮询。新代码推荐使用。

                代表性工具:bpftrace、BCC 工具集(biolatencytcpretransrunqlat 等)、Cilium、Falco、Tetragon。


                四、数据源之间的依赖与复用

                这是理解整个 Linux 可观测性工具体系的核心关键,也是最容易被忽视的底层逻辑。各类数据源与导出机制之间并非独立并列的关系,而是存在明确的分层依赖和多路复用关系。


                Tracepoint是核心生产者,ftrace、perf_events 和eBPF是并行消费渠道

                Tracepoint 是内核预先埋好的稳定插桩点,采用发布-订阅模式工作。同一个 Tracepoint(如进程调度事件 sched:sched_switch)触发时,所有已注册的消费者都会同时收到事件通知,彼此完全独立、互不干扰。

                内核 Tracepoint 触发├─ 已订阅 ftrace      → 事件写入 ftrace ring buffer → trace-cmd 读取解析├─ 已订阅 perf_events → 事件写入 perf ring buffer   → perf 工具读取解析└─ 已 attach BPF 程序 → 直接执行 BPF 处理逻辑       → 数据写入 BPFMap/RingBuf → bpftrace/BCC 读取

                核心特性:同一个 Tracepoint 在内核中只有一个代码插桩点,但可以同时被多个观测者订阅。这意味着可以同时运行 trace-cmdperf record 和 bpftrace 追踪同一个事件,不会产生额外的插桩开销。


                perf_events 是 eBPF 的关键触发与数据传输机制

                eBPF 不仅可以直接消费 Tracepoint 和 kprobe/uprobe 事件,还与 perf_events 子系统深度融合,后者是 eBPF 实现采样类观测和高性能数据传输的基础。

                • BPF_PROG_TYPE_PERF_EVENT 程序类型:允许 BPF 程序 attach 到任意 perf_event 上,事件触发时执行对应的 BPF 程序。支持的事件类型包括 PMU 硬件性能事件、内核软件事件(如时钟、上下文切换)、Tracepoint 事件等。

                • On-CPU 性能剖析的标准实现:bpftrace/BCC 中的 profile 工具通过 perf_events 子系统设置 99Hz 的软件时钟事件(SW_CPU_CLOCK)。每次时钟中断触发时,perf_events 调用已 attach 的 BPF 程序,由 BPF 程序在内核态采集当前 CPU 的调用栈并更新聚合 Map。整个流程中,perf_events 负责定时采样触发,eBPF 负责内核态数据处理与聚合,二者是典型的协作关系。

                使用 99Hz 而非 100Hz,是为了避免与内核定时器频率(CONFIG_HZ 常见值为 100、250、1000)产生相位锁定,防止采样反复落在相同代码位置导致火焰图失真。

                • BPF_MAP_TYPE_PERF_EVENT_ARRAY 数据传输:这是 Linux 5.8 之前 BPF 程序向用户态传输数据的主要方式,数据流向为:BPF 程序 → perf ring buffer → 用户态通过 perf_events 系统调用读取。Linux 5.8 之后新增了性能更优的 BPF_MAP_TYPE_RINGBUF,但 PERF_EVENT_ARRAY 仍被广泛兼容使用。


                kprobe 和 uprobe 的双重消费路径

                kprobe(内核动态插桩)和 uprobe(用户态动态插桩)同样支持多路复用,可以被 perf_events 和 eBPF 两种方式独立消费:

                • perf probe 方式:通过 perf probe 命令动态添加 kprobe/uprobe 插桩点,由 perf_events 子系统负责事件采集和存储,最终通过 perf record 写入 perf.data 文件,事后使用 perf report 分析。

                • eBPF 直接 attach 方式:BPF 程序直接 attach 到 kprobe/uprobe 插桩点,事件触发时立即执行 BPF 处理逻辑,数据通过 BPF Map 或 RingBuf 实时传出到用户态。

                关键区别:两者追踪的是同一个内核插桩点,但数据处理能力不同。perf probe 主要用于记录原始事件并提供基础过滤功能;eBPF 支持在内核态进行复杂的过滤、聚合、计算和状态维护,大幅减少需要传输到用户态的数据量。


                cBPF:eBPF 的历史前身,至今仍在广泛运行

                tcpdump 和 libpcap 使用的 BPF 其实是 cBPF(Classical BPF,经典 BPF)。这项技术最早于 1992 年在 BSD 系统中诞生,Linux 内核在 2.2 版本(1999 年)引入,比 eBPF 早了 15 年,也是 eBPF 名称中「BPF」的来源。

                cBPF 专门用于网络数据包过滤,运行在 AF_PACKET socket 的数据包接收路径上。其核心作用是让用户在内核态指定过滤规则(如「只捕获目标端口 80 的 TCP 包」),只有符合规则的数据包才会被复制到用户态,极大降低了数据包捕获的系统开销。

                tcpdump 完整工作流程

                用户输入过滤表达式(如 tcp port 80 and host 192.168.1.1  → libpcap 将表达式编译为 cBPF 字节码  → 通过 SO_ATTACH_FILTER socket 选项将字节码加载到内核  → 内核在每个收到的数据包上执行 cBPF 过滤  → 符合条件的数据包通过 AF_PACKET socket 复制到用户态  → tcpdump 解析并展示
                现代内核的融合:从 Linux 3.18 开始,内核会自动将 cBPF 程序转换为 eBPF 字节码执行,共享同一套验证器和 JIT 编译引擎。cBPF 和 eBPF 是同一内核 BPF 子系统的两种前端接口。

                历史演进:cBPF(1992,BSD 包过滤)→ Linux cBPF(1999,Linux 2.2)→ eBPF(2014,Linux 3.18,通用可编程内核扩展)


                核心关系全景总结

                # Tracepoint 多路消费(数据从左向右流动)Tracepoint    →  ftrace ring buffer   →  trace-cmdTracepoint    →  perf ring buffer     →  perf 工具Tracepoint    →  eBPF 程序            →  BPF Map/RingBuf  →  bpftrace/BCC# 动态插桩多路消费kprobe/uprobe →  perf ring buffer     →  perf 工具kprobe/uprobe →  eBPF 程序            →  BPF Map/RingBuf  →  bpftrace/BCC# perf_events 触发与采样PMU 硬件      →  perf_events 采样     →  perf stat/recordSW_CPU_CLOCK  →  perf_events 采样     →  eBPF 程序(On-CPU 剖析)→  BPF Map# 网络相关 BPFAF_PACKET     →  cBPF 过滤            →  tcpdump/libpcap(符合条件的包)XDP Hook      →  eBPF 程序            →  BPF Map/转发/丢弃(网卡驱动层)TC Hook       →  eBPF 程序            →  BPF Map/流量控制(协议栈流量控制层)

                五、工具与数据源的完整映射


                /proc 和 /sys 工具族(聚合计数器消费者)

                共同特征:周期性读取 /proc 或 /sys 文件,做差分计算速率,展示聚合指标。数据是内核预定义的计数器,无法自定义观测维度。

                vmstat:组合读取 /proc/stat(CPU)、/proc/vmstat(内存分页事件)、/proc/diskstats(I/O)、/proc/meminfo(内存用量),每行是多个文件的聚合展示。

                iostat:读取 /proc/diskstats,计算每个块设备的 IOPS、带宽、utilization、await、avgqu-sz。只能看块设备层的聚合平均值,无法看单次 I/O 的延迟分布。

                sar:定期读取几乎所有 /proc 文件并保存历史,覆盖面最广,适合查询历史趋势。

                netstat:解析 /proc/net/tcp/proc/net/udp 等文本文件。socket 数量多时极慢,推荐以 ss 替代。

                ss:通过 netlink socket 直接查询内核 socket 状态,速度远快于 netstat,支持条件过滤,是查询连接状态的推荐工具。

                iotop:主要通过 Taskstats netlink 接口获取进程级 I/O 统计,辅以 /proc/PID/io。Taskstats 比 /proc/PID/io 更完整,能追踪已退出进程的数据。

                slabtop:读取 /proc/slabinfo,展示内核 slab 缓存使用情况,是发现内核内存异常增长的入口工具。

                numastat:读取 /sys/devices/system/node/ 下的统计,展示每个 NUMA 节点的内存分配命中/未命中,是排查跨节点内存访问性能问题的第一步。


                perf 工具族(perf_events 消费者)

                通过 perf_event_open() 访问 perf_events 子系统,数据经 mmap 环形缓冲区传递,支持高频采样。

                perf stat:以计数模式访问 PMU,统计指令数、时钟周期、LLC 缺失等硬件事件,计算 IPC 和缓存命中率。与 vmstat 的本质区别:vmstat 读取 /proc/stat 的软件估算值,perf stat 读取 CPU 硬件计数器的精确值。

                perf record:以采样模式访问 PMU 或 Tracepoint,每 N 次事件采样一次调用栈,写入 perf.data。perf record -F 99 -ag 是生成 On-CPU 火焰图的标准命令。

                perf annotate:将 perf record 采样数据注释到源码和汇编指令层面,可精确到哪条汇编指令最热,是 BPF 工具无法提供的粒度。

                perf probe:在内核或用户态任意位置动态添加 kprobe/uprobe,通过 perf_events 导出,使 perf 能追踪 Tracepoint 未覆盖的内核函数。

                perf ftrace:调用 ftrace function tracer 能力,在 perf 接口下追踪内核函数调用树,是 perf 与 ftrace 两个子系统的交叉点。

                perf sched:基于 sched:* Tracepoint,分析调度延迟、进程等待时间、CPU 迁移。perf sched latency 汇总各进程的最大/平均调度延迟,是识别调度抖动根因的核心命令。

                perf mem:利用硬件采样能力(Intel PEBS、AMD IBS)在硬件层面采样内存访问,精确区分 L1/L2/L3 cache hit 和 DRAM 访问,定位内存访问热点。依赖 CPU 厂商的精确采样特性支持。

                perf c2c:检测多核程序中的伪共享(false sharing)和 NUMA 跨节点访问,精确定位频繁被多线程竞争访问的 cache line 及对应代码位置。

                perf lock:基于 lock:* Tracepoint 统计内核锁的竞争情况(持锁时间、等待时间、竞争次数),是诊断内核锁竞争瓶颈的专用工具。

                perf trace:通过 syscalls: Tracepoint 实现系统调用追踪,开销约比 strace 低一到两个数量级,可在生产环境有限度使用,格式与 strace 相近。


                ftrace 工具族(ftrace ring buffer 消费者)

                trace-cmd:ftrace 的命令行前端,封装了 /sys/kernel/debug/tracing/ 下的繁琐文件操作,支持录制 Tracepoint 事件和函数追踪数据,配合 kernelshark 可视化分析。

                独特场景:function_graph tracer 可追踪某个内核函数的完整调用子树,看到精确的调用顺序和每个子函数的执行时间,这是 perf 和 BPF 工具均无法直接替代的能力。

                latency tracer:irqsoff tracer(中断禁用时长)、preemptoff tracer(抢占禁用时长)、wakeup tracer(最高优先级进程唤醒延迟),是低延迟和实时系统问题诊断的专用工具。


                BPF 工具族(eBPF 可编程框架消费者)

                通过 kprobe、Tracepoint、uprobe、USDT、PMU/软件时钟事件的任意组合采集数据,在内核态预聚合后通过 BPF Map 或 ring buffer 传给用户态。

                biolatency:attach 到 block_rq_issue 和 block_rq_complete(Tracepoint),在内核态计算每次 I/O 延迟并更新直方图 Map。与 iostat 的本质区别:iostat 只能看聚合平均值,biolatency 提供完整延迟分布(含 p99 和长尾)。

                tcpretrans:attach 到 tcp_retransmit_skb(kprobe),每次 TCP 重传时记录四元组和进程信息。这类信息在 /proc 里完全不可见,是 BPF 独有的能力。

                runqlat:attach 到 sched_wakeup 和 sched_switch(Tracepoint),在内核态计算调度延迟并展示直方图。

                offcputime:attach 到 sched_switch(Tracepoint),在进程被调度出 CPU 时记录调用栈、调度回时累积 Off-CPU 时间,生成 Off-CPU 火焰图,用于分析锁等待、I/O 等待等非 CPU 阻塞原因。

                profile(On-CPU profiling):通过 perf_events 以 99Hz 触发软件时钟采样(BPF_PROG_TYPE_PERF_EVENT),每次触发时在内核态采集调用栈并更新计数 Map,生成 On-CPU 火焰图。数据处理在 BPF 程序内完成,不经过 perf ring buffer。


                网络专项工具族

                tcpdump / Wireshark:通过 libpcap 和 AF_PACKET socket 捕获原始数据包。libpcap 将过滤表达式编译为 cBPF 字节码,通过 SO_ATTACH_FILTER 加载到内核,在收包路径上过滤,只将符合条件的数据包复制到用户态。适合协议分析,不适合性能指标分析。

                tcpretrans 类 eBPF 工具:追踪 TCP 连接状态变化事件(kprobe),不捕获数据包内容,但可关联到具体进程和调用栈。与 tcpdump 的数据源和适用场景完全不同。

                XDP:eBPF 在网卡驱动层的 hook,数据包进入内核协议栈前执行 BPF 程序,无需内存复制,可实现极低延迟的包过滤、转发和负载均衡。Cilium、Katran 等高性能网络组件均大量使用。

                ss / netstat:查询当前活跃 socket 状态快照,解答"现在系统有哪些连接",与 tcpdump 的实时流量捕获定位不同。

                iperf / qperf:主动发起网络压测,直接测量端到端带宽和延迟,属于主动探测而非被动观测,不依赖任何内核导出接口。


                能耗与频率工具族

                turbostat:通过 /dev/cpu/*/msr 读取 RAPL 能耗计数器,展示每个 CPU 核的实时频率、功耗、温度、C-state 停留时间。分析因温度过高触发降频导致延迟抖动的核心工具,仅支持 x86/x86-64,云虚拟机环境通常无法访问 MSR。


                六、数据源的能力边界

                不同数据源在几个关键维度上有明确的能力边界,决定了什么工具能回答什么问题。


                时间分辨率

                /proc 系工具的时间分辨率受限于轮询频率,通常是秒级。一个持续 100ms 的磁盘延迟毛刺,在 iostat 里会被平摊到整个采样周期,看起来只是 await 轻微升高。

                Tracepoint 和 kprobe 有纳秒级时间分辨率,每次事件都有精确时间戳,能捕获并记录示例 100ms 的延迟毛刺及其分布。

                PMU 和软件时钟采样的分辨率取决于采样频率,99Hz 意味着约 10ms 的采样间隔——足以用于 CPU profiling,但不足以捕获微秒级事件。

                PSI 提供 10s、60s、300s 三个滑动窗口的均值,适合趋势判断,不适合瞬时诊断。


                单次事件 vs 聚合统计

                /proc 和 /sys 只有聚合统计,没有单次事件的记录。能看到"过去 1 秒平均有 100 次 I/O",但看不到"第 37 次 I/O 的延迟是 800ms"。

                Tracepoint、kprobe、PMU 采样都能提供单次事件的记录(时间戳、上下文、调用栈)。BPF 工具可以在内核态对单次事件做阈值过滤(只记录延迟超过 10ms 的那次),避免数据量爆炸。


                调用栈(代码路径)信息

                /proc 系工具完全没有调用栈信息,只有聚合指标。

                perf record 和 BPF 工具可以采集调用栈,把延迟或 CPU 时间分配到具体的代码路径,这是生成火焰图的基础。

                调用栈采集的可靠性在内核空间和用户空间有所不同:

                内核空间:Linux 4.14 引入 ORC(Oops Rewind Capability)unwinder,不依赖帧指针即可可靠展开内核栈,内核空间的调用栈问题已基本解决。

                用户空间:GCC 默认以 -fomit-frame-pointer编译,导致大量用户态程序缺少帧指针,调用栈出现 [unknown]帧,火焰图价值大打折扣。这是发行版层面的工程问题——Fedora 38+、Ubuntu 24.04+ 等已在打包时默认恢复帧指针,但存量程序仍受影响,可用 DWARF 展开(perf record --call-graph dwarf)作为替代,代价是更高的采样开销。


                  进程级别 vs 系统级别

                  /proc系工具多为系统级别的全局统计,无法区分是哪个进程触发了某次事件。Taskstats netlink 接口和 BPF 工具可以把事件关联到具体进程,且 BPF 工具能在关联进程信息的同时记录调用栈,把"谁"、"做了什么"、"花了多久"整合到同一条记录里。


                  跨层关联

                  这是 BPF 相对于其他所有数据源的独特能力。传统工具每个只看一层:iostat 看块设备层,netstat 看网络层,top 看进程层,各层数据无法关联。

                  BPF 可以同时在多层插桩,用共享 Map(以进程 ID 或请求 ID 为 key)把不同层的事件串联,回答「这个 MySQL 查询的延迟有多少来自磁盘 I/O、多少来自锁等待、多少来自纯 CPU 计算」这类需要跨层视角的问题。


                  七、strace 的特殊位置

                  strace 值得单独讨论,因为它的实现机制与上述所有工具都不同,也是最容易被错误使用的工具。


                  工作机制与开销

                  strace 使用 ptrace 系统调用追踪目标进程的系统调用。每当目标进程执行系统调用的进入和返回时,内核暂停目标进程并通知 strace,strace 处理完后内核才恢复目标进程。

                  每个被追踪的系统调用因此产生两次上下文切换(目标进程 → strace → 目标进程),开销与系统调用频率成正比。对于高频系统调用(如 writereadsendmsg),这个开销可以让服务吞吐量下降 10 倍以上。

                  strace 不属于 /proc、Tracepoint 或 kprobe 任何一类,而是通过进程暂停-检查-恢复的方式工作,是所有追踪工具里开销最大的一种。


                  使用原则

                  生产环境禁止使用 strace。 需要追踪生产环境系统调用时,应使用:

                  • perf trace:通过 syscalls:Tracepoint 实现,格式接近 strace,开销低一到两个数量级;

                  • bpftrace -e 'tracepoint:syscalls:sys_enter_xxx':BPF 方式,支持自定义过滤和聚合,灵活度更高。

                    strace 唯一合理的场景:调试环境,理解某个程序调用了哪些系统调用(如分析二进制程序行为、调试启动失败原因)。


                    八、Linux 性能可观测性体系全景


                    【硬件层】

                    硬件
                    提供的数据
                    CPU
                    PMU 计数器(指令数、时钟周期、缓存缺失等)、RAPL 能耗、MSR 寄存器
                    磁盘控制器
                    I/O 完成中断
                    网卡
                    数据包收发硬件事件
                    内存控制器
                    NUMA 访问事件

                    【内核事件源层】基于五大类拆分

                    内核计数器(第一层事件源,通过 /proc /sys /cgroup 导出)  └─ 调度、I/O、内存、网络子系统自动维护的累积计数  └─ PSI(Linux 4.20,压力停顿信息,最直接的系统压力指标)  └─ cgroup v2 提供统一的 io.stat(v1 需区分 blkio.io_service_bytes 和 throttle.*)Tracepoint → 内核关键路径的稳定静态插桩点(ABI 稳定,跨版本可靠)  └─ 多消费者:ftrace ring buffer、perf_events、eBPF 可同时订阅同一插桩点kprobe / uprobe → 任意内核/用户态函数的动态插桩点  └─ x86_64:int3(0xCC)+ jump optimization(5 字节 JMP)  └─ ARM64:BRK 指令 + 定长 4 字节 patch  └─ 消费方式:perf_events 或 eBPF 直接 attachUSDT → 应用程序主动埋设的用户态静态插桩点,基于 uprobe 实现  └─ semaphore 机制保证未激活时零开销,不受函数内联和版本改名影响  └─ MySQL、PostgreSQL、Node.js、Python 等内置大量探针PMU 硬件计数器 → CPU 微架构级别事件(指令数、LLC 缺失、分支预测失败等)  └─ 通过 perf_events 子系统消费(计数模式 / 采样模式)  └─ eBPF 可 attach 到 PMU 采样事件(BPF_PROG_TYPE_PERF_EVENT)SW_CPU_CLOCK → 内核软件时钟事件(非 PMU 硬件事件)  └─ 触发 eBPF 程序进行 On-CPU profiling(profile 工具的默认采样源)XDP(eXpress Data Path)→ eBPF 在网卡驱动层的 hook  └─ 数据包进入协议栈前执行,sk_buff 分配前处理,无内存复制开销  └─ 支持极低延迟的包过滤、转发、负载均衡cBPF(AF_PACKET socket 过滤)→ 经典包过滤机制,eBPF 的历史前身  └─ tcpdump/libpcap 将过滤表达式编译为 cBPF 字节码,在收包路径内核侧过滤  └─ 现代内核自动将 cBPF 转换为 eBPF 字节码执行,共享同一套 JIT 引擎

                    【内核数据导出层】

                    /proc /sys 虚拟文件系统  └─ 文本轮询,聚合指标(含 PSI、cgroup v1/v2 stat  └─ 接口简单,无需特殊权限,始终可用;无单次事件详情perf_events 子系统  └─ 统一事件订阅框架,PMU / Tracepoint / kprobe / uprobe 均可注册  └─ 数据经 mmap 环形缓冲区传递;BPF_MAP_TYPE_PERF_EVENT_ARRAY 是旧版 BPF 传输方式ftrace ring buffer  └─ 内核函数追踪和 Tracepoint 事件记录  └─ 与 perf_events 消费同一 Tracepoint 事件源,两者可同时订阅,互不干扰  └─ function_graph tracer 可展示完整函数调用子树(perf/BPF 无法直接替代)netlink socket  └─ 网络子系统查询(ss)、进程任务统计(Taskstats / iotop)、网络事件通知eBPF Maps + ring buffer  └─ 可编程数据处理层:在内核态完成过滤、聚合、变换,只将结果传给用户态  └─ BPF_MAP_TYPE_RINGBUF(5.8+):全局共享、保序、支持 reserve+commit 两阶段写入  └─ BTF/CO-RE(5.4-5.5 实用)保证跨内核版本可移植,无需目标机器内核头文件  └─ Verifier 在程序加载时静态分析,保证有界、内存安全、helper 合法MSR 寄存器接口(x86/x86-64 专有)  └─ 能耗(RAPL)、频率、温度数据,通过 /dev/cpu/*/msr 访问  └─ 云虚拟机通常屏蔽;ARM64 无此接口

                    【用户态工具层】

                    +----------------------+------------------------------------------------------------------+| 工具体系              | 核心工具列表 / 机制说明                                          |+----------------------+------------------------------------------------------------------+| /proc 系             | top, vmstat, iostat, sar, netstat, free, slabtop, dstat          |+----------------------+------------------------------------------------------------------+| cgroup / PSI 系      | cadvisor, docker stats, systemd-oomd                             |+----------------------+------------------------------------------------------------------+| NUMA 系              | numastat, numactl                                                |+----------------------+------------------------------------------------------------------+|                      | perf stat, perf record, perf annotate, perf probe, perf ftrace,  || perf 系              | perf sched, perf mem, perf c2c, perf lock, perf trace            |+----------------------+------------------------------------------------------------------+| ftrace 系            | trace-cmd, kernelshark, irqsoff tracer, wakeup tracer            |+----------------------+------------------------------------------------------------------+|                      | bpftrace                                                         || BPF 系               | BCC 工具集:biolatency, tcpretrans, runqlat, offcputime, profile ||                      | 云原生:Cilium, Falco, Tetragon                                  |+----------------------+------------------------------------------------------------------+| 网络专项              | tcpdump(cBPF), Wireshark, ss, iperf, XDP-based 工具            |+----------------------+------------------------------------------------------------------+| 能耗频率(x86 专有)   | turbostat                                                        |+----------------------+------------------------------------------------------------------+|                      | strace(ptrace 机制,每次系统调用产生两次上下文切换,            || 特殊                  | 开销极高,仅用于调试环境)                                       |+----------------------+------------------------------------------------------------------+

                    横向关系:同一事件在不同工具的多维度呈现

                    这是理解 Linux 可观测性体系最实用的视角:同一个底层事件,不同工具从不同抽象层次、不同时间粒度、不同数据维度呈现,解决不同阶段的问题

                    一次磁盘 I/O 事件

                    iostat:看到1 秒 / 多秒聚合的平均指标(await、IOPS、utilization),来自 /proc/diskstats 预计算计数器。只能知道 "磁盘整体慢了",无法区分是少量极慢请求还是大量正常请求。

                    biolatency:看到每次 I/O 的精确延迟值和完整分布直方图(含 p50/p95/p99 长尾延迟),基于 block_rq_issue和 block_rq_complete两个 Tracepoint + eBPF 内核态聚合。能回答 "到底有多慢" 的问题。

                    blktrace/trace-cmd:看到单次 I/O 在块层全生命周期的所有阶段时间戳(排队、调度、驱动执行、完成),基于 ftrace ring buffer。能深入分析 "I/O 慢在哪个环节"。

                    perf record -e block:block_rq_complete -g:看到每次 I/O 完成时的完整调用栈(哪个进程、哪个函数发起了这次 I/O),基于Tracepoint + perf_events 事件触发(非采样)。能回答 "谁在发起慢 I/O"。

                    一次 TCP 重传事件

                    netstat -s / ss -s:看到系统全局 TCP 重传段计数器(RetransSegs)的增量,来自 /proc/net/snmp。只能知道 "系统有重传发生",无法定位具体连接和进程。

                    tcpretrans:看到每次重传的四元组、进程 PID、重传次数和时间戳,基于 tcp_retransmit_skb kprobe + eBPF。能精确定位 "哪个进程的哪个连接在重传"。

                    tcpdump/Wireshark:看到重传数据包的完整二进制内容(序列号、窗口大小、选项等),基于 cBPF + AF_PACKET 原始包捕获。能深入分析 "为什么会重传"(丢包、乱序、超时)。

                    CPU 利用率 90% 现象

                    top/vmstat:看到1 秒 / 多秒聚合的 CPU 时间分配比例(用户态、内核态、空闲等),来自 /proc/stat计数器。只能知道 "CPU 忙",无法区分是有效计算还是效率低下。

                    perf stat:看到PMU 硬件精确计数的 CPU 微架构指标(IPC、缓存命中率、分支预测错误率等)。能判断 "CPU 是真忙还是瞎忙"(例如 IPC<0.5 通常说明 CPU 大部分时间在等待内存)。

                    perf record -F 99 -g / BPF profile:看到消耗 CPU 时间的代码路径分布(调用栈聚合火焰图)。能精确定位 "哪段代码在消耗 CPU"。turbostat:看到每个 CPU 核的实时运行频率、功耗、温度和 C-state 停留时间,来自 MSR 寄存器。能发现 "CPU 看起来忙但性能上不去" 的隐藏原因(如温度过高触发降频、过度进入深度 C-state)。


                    九、选择工具的决策框架

                    开始├─ 问题1:需要历史趋势还是实时诊断?│  ├─ 历史趋势 → 系统级:sar(持续记录/proc数据)│  │              业务级:Prometheus + Grafana 监控系统│  └─ 实时诊断 → 进入问题2├─ 问题2:需要聚合指标还是事件/分布数据?│  ├─ 聚合指标(平均值、总量、比例)→ 进入问题3A│  └─ 事件/分布数据(单次事件、p50/p99长尾、直方图)→ 进入问题3B├─ 问题3A:聚合指标 → 需要哪个层次的视角?│  ├─ 系统全局资源 → /proc系工具:vmstat、iostat、free、sar、PSI│  ├─ 进程级资源使用 → top、pidstat、iotop、ss│  ├─ cgroup/容器级 → docker stats、cadvisor、cgroup v2 stat文件│  └─ 能耗与频率 → turbostat(CPU频率、功耗、温度)├─ 问题3B:事件/分布数据 → 需要哪个层次的视角?│  ├─ 系统级延迟分布 → BPF工具:biolatency(IO)、runqlat(调度)、tcpdrop(网络丢包)│  ├─ 进程级行为追踪 → perf trace(系统调用)、bpftrace(自定义追踪)│  ├─ 代码路径级热点 → perf record + 火焰图、BPF profile(On-CPU/Off-CPU)│  ├─ 微架构效率分析 → perf stat(PMU计数:IPC、缓存命中率、分支预测错误率)│  ├─ 专项深度问题│  │  ├─ 缓存伪共享/NUMA → perf c2c、perf mem│  │  ├─ 内核锁竞争 → perf lock、BPF offcputime│  │  ├─ 调度延迟/CPU迁移 → perf sched、BPF runqlat│  │  └─ 网络协议细节 → tcpdump/Wireshark(原始包分析)│  └─ 跨层关联分析(如"哪个SQL触发了哪些磁盘IO")→ 仅BPF工具支持└─ 问题4:工具是否适合生产环境运行?   ├─ ✅ 可长期运行(开销<1%)   │  ├─ 所有/proc/sys系工具(top、vmstat、iostat、sar、ss)   │  ├─ perf stat(计数模式)   │  └─ 低频率BPF聚合工具(如10秒一次的biolatency)   ├─ ⚠️ 可短期运行(开销1%-5%,不建议超过30分钟)   │  ├─ perf record(99Hz采样)   │  ├─ 中等频率BPF追踪工具   │  └─ trace-cmd(轻量事件录制)   └─ ❌ 禁止在生产环境运行(开销>20%,会影响业务)      ├─ strace/ltrace(ptrace机制)      ├─ 高频perf采样(>1000Hz)      ├─ 全量tcpdump抓包(千兆以上流量)      └─ 无过滤的kprobe追踪(如追踪所有内核函数)

                    结语

                    Linux 性能工具看似功能重叠,本质是不同工具对各类数据源的精准适配。本文梳理的核心逻辑可总结为:同一内核事件可被多种渠道消费,而不同数据通道的能力差异,直接决定了工具的观测边界与适用场景。

                    /proc 系工具用最低的开销提供系统级聚合视图;perf_events 统一了多种事件源的订阅框架,既服务 perf 工具族,也作为 eBPF 的触发机制;ftrace 提供函数级别的执行路径追踪;eBPF 在 Tracepoint、kprobe、perf_events 等多种事件源之上构建了可编程的跨层关联分析能力,BTF/CO-RE 解决了跨内核版本的可移植问题,验证器保证了内核安全;cBPF 在数据包过滤路径上运行了三十年;XDP 把 eBPF 的能力推进到网卡驱动层;MSR 接口直接触达硬件能耗和频率状态。

                    每种工具都功能局限。理解其间的数据流关系,就理解了每种工具的能力边界,也就知道了面对不同的问题应该选择哪种工具,以及为什么只用一种工具永远不够。

                    性能分析不是"找到最强的工具用它解决所有问题",而是"理解每种数据源能提供什么信息,按问题的需要组合使用"。这才是 Linux 性能分析工具体系的真正使用方式。


                    最新文章

                    随机文章

                    基本 文件 流程 错误 SQL 调试
                    1. 请求信息 : 2026-07-02 23:26:32 HTTP/2.0 GET : https://f.mffb.com.cn/a/499658.html
                    2. 运行时间 : 0.121399s [ 吞吐率:8.24req/s ] 内存消耗:4,696.54kb 文件加载:140
                    3. 缓存信息 : 0 reads,0 writes
                    4. 会话信息 : SESSION_ID=26a1594cd530e2a20acf1dc63e2bb779
                    1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
                    2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
                    3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
                    4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
                    5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
                    6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
                    7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
                    8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
                    9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
                    10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
                    11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
                    12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
                    13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
                    14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
                    15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
                    16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
                    17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
                    18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
                    19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
                    20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
                    21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
                    22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
                    23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
                    24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
                    25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
                    26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
                    27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
                    28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
                    29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
                    30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
                    31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
                    32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
                    33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
                    34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
                    35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
                    36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
                    37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
                    38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
                    39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
                    40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
                    41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
                    42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
                    43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
                    44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
                    45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
                    46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
                    47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
                    48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
                    49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
                    50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
                    51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
                    52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
                    53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
                    54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
                    55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
                    56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
                    57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
                    58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
                    59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
                    60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
                    61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
                    62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
                    63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
                    64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
                    65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
                    66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
                    67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
                    68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
                    69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
                    70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
                    71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
                    72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
                    73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
                    74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
                    75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
                    76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
                    77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
                    78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
                    79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
                    80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
                    81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
                    82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
                    83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
                    84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
                    85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
                    86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
                    87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
                    88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
                    89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
                    90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
                    91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
                    92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
                    93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
                    94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
                    95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
                    96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
                    97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
                    98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
                    99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
                    100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
                    101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
                    102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
                    103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
                    104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
                    105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
                    106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
                    107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
                    108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
                    109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
                    110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
                    111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
                    112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
                    113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
                    114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
                    115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
                    116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
                    117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
                    118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
                    119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
                    120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
                    121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
                    122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
                    123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
                    124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
                    125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
                    126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
                    127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
                    128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
                    129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
                    130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
                    131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
                    132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
                    133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
                    134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
                    135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
                    136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
                    137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
                    138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
                    139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
                    140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
                    1. CONNECT:[ UseTime:0.000701s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
                    2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000826s ]
                    3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000346s ]
                    4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000338s ]
                    5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000533s ]
                    6. SELECT * FROM `set` [ RunTime:0.000199s ]
                    7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000578s ]
                    8. SELECT * FROM `article` WHERE `id` = 499658 LIMIT 1 [ RunTime:0.000693s ]
                    9. UPDATE `article` SET `lasttime` = 1783005992 WHERE `id` = 499658 [ RunTime:0.019375s ]
                    10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000316s ]
                    11. SELECT * FROM `article` WHERE `id` < 499658 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000466s ]
                    12. SELECT * FROM `article` WHERE `id` > 499658 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002991s ]
                    13. SELECT * FROM `article` WHERE `id` < 499658 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002776s ]
                    14. SELECT * FROM `article` WHERE `id` < 499658 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001016s ]
                    15. SELECT * FROM `article` WHERE `id` < 499658 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000764s ]
                    0.123010s