如何生成火焰图?

解读

在国内 Rust 岗位面试中,“火焰图” 已不仅是性能调优的“加分项”,而是区分初中高级工程师的硬指标
面试官真正想听的是:

  1. 你是否亲手在 Linux 生产环境定位过 CPU/Off-CPU 热点;
  2. 能否用 Rust 生态原生工具(而非照搬 C/C++ 那套 perf 脚本)快速给出可复现、可自动化的火焰图流程;
  3. 对容器、权限、符号解析等国内云厂商常见卡点是否有踩坑经验。
    回答时务必先给端到端命令,再解释原理,最后补一句“我们线上用 GitLab CI 每晚自动出图”,瞬间拉满可信度。

知识点

  • 采样原理:perf Events → 调用栈 → 折叠格式 → SVG
  • Rust 符号可见性[profile.release] debug = true + split-debuginfo = "packed"国内镜像源常把 debug 裁掉,必须显式打开
  • 两种主流方案
    cargo-flamegraph(一键,适合开发机)
    perf + inferno(容器/CI,权限可控,可区分 On/Off-CPU)
  • 权限与内核
    – Ubuntu 20+ 需 echo 1 > /proc/sys/kernel/perf_event_paranoid
    – 容器内要加 --cap-add SYS_ADMIN --security-opt seccomp=unconfined阿里云 ACK、腾讯云 TKE 默认没给
  • 符号解析踩坑
    – 若出现 ???,先检查 /proc/kallsyms 是否可读,再确认二进制带 .debug_frame
    – 国内镜像构建阶段常 strip,CI 里加 objcopy --only-keep-debug 单独保存 dbg 文件,运行时挂载进容器
  • Off-CPU 扩展:用 perf record -e sched:sched_switchinferno-collapse-perf --event-filter="sched:sched_switch"定位 async Rust 阻塞点(如 tokio mutex)

答案

(给出可直接抄的国内云主机可复现步骤,假设项目名 demo,已装 rustup)

  1. 让发布二进制带符号
# Cargo.toml 末尾追加
[profile.release]
debug = true        # 必须,否则只看到地址
lto = "thin"        # 可选,减小体积
  1. 安装工具链
# 用清华源加速
export RUSTUP_DIST_SERVER=https://mirrors.tuna.tsinghua.edu.cn/rustup
rustup component add llvm-tools-preview
cargo install flamegraph --version 0.6.3  # 锁定版本,防止 CI 抖动
  1. 采样 + 生成(最常用单命令
sudo sysctl -w kernel.perf_event_paranoid=1   # 阿里云默认 2,需改
cargo build --release
sudo flamegraph --freq 997 --output cpu.svg -- ./target/release/demo -w 24

解释:--freq 997 避开 1000 Hz 电源管理共振;-w 24 是业务参数,让程序跑 30 s 以上,采样更稳。

  1. 浏览器打开 cpu.svgRust 函数名完整可见,热点行直接映射到源码行号。

  2. CI 自动化(.gitlab-ci.yml 片段)

perf:
  stage: test
  image: rust:1.75-slim
  before_script:
    - apt-get update && apt-get install -y linux-perf sudo
    - echo 1 | sudo tee /proc/sys/kernel/perf_event_paranoid
  script:
    - cargo build --release
    - cargo install flamegraph
    - sudo flamegraph --freq 997 --output flame.svg -- ./target/release/demo -w 24
  artifacts:
    paths: [flame.svg]
    expire_in: 1 week

每晚定时跑,MR 里直接看图,性能回退立即打回

拓展思考

  • async 火焰图:tokio 的 console-subscriber + tokio-console 可生成异步状态机火焰图,弥补 perf 看不到调度器内部切换的盲区;国内长链接网关常用此法定位 spawn_blocking 池耗尽。
  • 内存火焰图heaptrack 导出折叠格式后 inferno-collapse-stackmemory.svg在区块链节点大内存场景比 CPU 图更关键。
  • Windows 场景:国内游戏服务端不少用 Windows Server,可用 cargo-profdata + llvm-xray 生成 .xray 文件,再转 SVG,思路同 Linux,但需装 LLVM 15+
  • 安全合规:金融云环境禁止 sudo,可改用用户态 PMU perf_event_openexclude_kernel=1采样精度下降但可过审;此时把频率提到 9999 Hz 并加长运行时间,同样能定位业务热点