指标告诉你服务慢了,火焰图告诉你慢在哪一行。本文介绍炬鲸 OBSERVE 持续剖析:火焰图读法、低开销采样配置,以及 CPU、内存、锁竞争三个排障场景。
CPU 冲到 90%,接口 P99 从 50ms 涨到 300ms。指标告诉你"出事了",链路告诉你"慢在 order-service 这个服务",但要回答"到底哪段代码在吃 CPU、哪个对象在占内存",还得靠剖析(Profiling)。
老办法是出问题时临时挂一次 pprof 或 async-profiler,但等你连上去,流量峰值往往已经过去,抓不到现场。炬鲸 OBSERVE 的持续剖析把"临时抓包"变成"一直录着":默认每 60 秒采一次、每次采样约 10 秒,以 3% 以内的 CPU 开销持续记录各进程调用栈。出问题时可以直接回看过去 15 分钟甚至更长时间的栈快照,不用复现。
火焰图横轴代表采样占比,纵轴是调用栈,宽度越宽说明占用越高。看的时候按这个顺序:
一个常见误区是只看总宽度。真正该优化的是"自耗时"(self time)——函数自身代码的耗时,不含它调用的子函数。有些函数自己很窄,但被几万个调用点反复调用,加起来也很可观,这类要用"调用者视角"才能找出来。
在目标主机装一个采集代理,给进程打上标签即可,不用改业务代码。典型配置:
profiling:
enabled: true
interval: 60s
duration: 10s
targets:
- service: order-service
process: java
lang: jvm
cpu: true
alloc: true
JVM 服务建议同时开 CPU 和内存分配(alloc)两项;Go 服务用 pprof 的 CPU 与 heap;Node.js 重点看 event loop 阻塞与 GC。采样开销控制在 3% 以内,生产可以直接长开;也可以配置低峰期自动调高采样频率、高峰期自动调低。
建议把剖析和告警联动:CPU 或内存指标触发告警时,自动截取告警前后各 5 分钟的火焰图快照,省去人工复现,也方便事后复盘。