mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
3900 字
11 分钟
持续性能分析:第四大支柱
2025-08-25

三大信号(日志、指标、追踪)回答了”系统出了什么问题”和”问题在哪里”,但无法回答”代码为什么慢”。CPU 使用率 80% 是症状,哪个函数在消耗 CPU 才是根因。P99 延迟 2s 是症状,哪个调用栈导致了尾部延迟才是根因。

持续性能分析(Continuous Profiling)填补了这个空白——它持续采集程序的 CPU/内存/锁竞争等性能数据,生成火焰图,让你看到代码级别的性能热点。它不是按需触发的 perf record,而是始终在线的性能观测。

一、性能分析基础#

1.1 什么是性能分析?#

性能分析(Profiling)是通过采样(Sampling)来估算程序运行时行为的技术。它不是记录每一次函数调用,而是定期”拍照”——每隔一段时间记录当前的调用栈,然后用统计学方法估算各函数的 CPU/内存占比。

graph LR subgraph 采样过程 T1["t1: main→A→B→C"] T2["t2: main→A→B→D"] T3["t3: main→A→E"] T4["t4: main→A→B→C"] T5["t5: main→F→G"] end subgraph 聚合结果 AGG["main: 5 次<br/>A: 4 次<br/>B: 3 次<br/>C: 2 次<br/>D: 1 次<br/>E: 1 次<br/>F: 1 次<br/>G: 1 次"] end T1 --> AGG T2 --> AGG T3 --> AGG T4 --> AGG T5 --> AGG

1.2 采样 vs 追踪#

维度采样(Profiling)追踪(Tracing)
粒度函数调用栈请求级 Span
开销极低(~1-2%)中等(~5-15%)
观测对象CPU/内存/锁请求延迟/错误
回答的问题”哪个函数消耗 CPU?""哪个请求慢?“
数据量小(聚合后)大(每请求一条)

1.3 采样频率与误差#

采样频率CPU 开销误差适用场景
99 Hz~0.5%~10%生产环境持续采集
19 Hz~0.1%~25%低开销生产采集
999 Hz~5%~3%性能调优(短期)
4999 Hz~20%~1%精确分析(开发环境)
Note

采样频率使用”奇数 Hz”(如 99 而非 100)是为了避免与系统时钟周期同步,减少采样偏差。这是 Brendan Gregg 提出的最佳实践。

二、火焰图#

2.1 火焰图原理#

火焰图(Flame Graph)由 Brendan Gregg 于 2011 年发明,是性能分析最直观的可视化方式:

graph TB subgraph 火焰图 MAIN["main() — 100%"] A["A() — 80%"] B["B() — 60%"] C["C() — 40%"] D["D() — 20%"] E["E() — 20%"] F["F() — 20%"] G["G() — 20%"] end MAIN --> A MAIN --> F A --> B A --> E B --> C B --> D F --> G style MAIN fill:#e3f2fd,stroke:#1565c0 style C fill:#ffcdd2,stroke:#c62828 style D fill:#ffcdd2,stroke:#c62828
特征说明
X 轴调用栈宽度 = 采样命中次数(不是时间顺序)
Y 轴调用栈深度(底部是入口,顶部是叶子)
宽栈帧该函数消耗 CPU 最多(热点)
颜色通常无特殊含义,仅用于区分函数
交互点击栈帧可放大,搜索可高亮

2.2 火焰图阅读教程#

读火焰图是一门手艺。很多人第一次看到火焰图时,会被五颜六色的栈帧搞得一头雾水。其实掌握几个关键原则,就能快速定位性能热点。

原则一:看宽度,不看高度。 火焰图的 X 轴宽度代表采样命中次数,也就是 CPU 时间占比。一个栈帧越宽,说明它消耗的 CPU 越多。高度(调用栈深度)本身没有性能含义——深调用栈不一定慢,浅调用栈不一定快。

原则二:从底部向上看。 底部是程序入口(如 main()),向上是调用链的深入方向。热点函数通常出现在中间层——既不是最底层的入口,也不是最顶层的叶子,而是某个中间函数占据了大量宽度。

原则三:寻找”平台”。 如果某个栈帧特别宽,而它上面的子调用栈帧都很窄,说明这个函数本身(而非它的子调用)是 CPU 热点。这种”平台”结构是最容易优化的目标——你只需要优化这一个函数。

原则四:忽略小栈帧。 宽度不到总宽度 5% 的栈帧,即使优化了也不会有显著效果。把精力集中在占比超过 10% 的热点上。

2.3 如何从火焰图识别 CPU 瓶颈#

实际生产中,CPU 瓶颈通常表现为以下几种火焰图模式:

模式火焰图特征典型根因优化方向
计算密集某个函数形成宽平台算法复杂度高、序列化/反序列化优化算法、更换库
锁竞争futex_wait/mutex_lock 占比高并发冲突减少锁粒度、使用无锁结构
系统调用syscall/read/write 占比高I/O 密集异步 I/O、批量操作
GC 压力gc_mark/gc_sweep 占比高内存分配过多减少分配、对象池
调度延迟schedule/__schedule 占比高线程数过多、CPU 争抢减少 goroutine/线程数
Warning

火焰图只显示采样命中的调用栈,不显示等待时间。如果你的 CPU 使用率低但延迟高,应该看 Off-CPU 火焰图而非 CPU 火焰图。

2.4 火焰图类型#

类型观测对象用途
CPU 火焰图CPU 时间找到 CPU 热点函数
内存火焰图内存分配找到内存分配热点
Off-CPU 火焰图等待时间找到阻塞/等待热点
锁竞争火焰图锁等待时间找到锁竞争热点
差分火焰图两个时间点的差异对比优化前后

2.5 Off-CPU 火焰图#

CPU 火焰图只能看到”CPU 在做什么”,但看不到”CPU 在等什么”。Off-CPU 火焰图填补了这个空白:

bpftrace -e '
profile:hz:99 /pid == $1/ {
@[ustack] = count();
}
'
# 使用 perf 采集 Off-CPU 数据
perf record -e sched:sched_stat_sleep -p <pid> -- sleep 60
Warning

Off-CPU 火焰图的采集开销比 CPU 火焰图高得多,因为它需要追踪每次调度事件。在生产环境中使用时,务必限制采集时间和范围。

三、perf 工具详解#

3.1 perf 简介#

perf 是 Linux 内核自带的性能分析工具,是持续性能分析的基础设施。Parca Agent 和 Pyroscope 底层都依赖 perf 事件机制来采集调用栈。

perf list
# 常用事件
# instructions — 指令数
# branch-misses — 分支预测失败

3.2 perf record 采集#

# 采集 CPU 性能数据(默认 99 Hz)
perf record -g -p <pid> -- sleep 60
perf record -F 999 -g -p <pid> -- sleep 30
# 采集特定事件
perf record -e cache-misses -g -p <pid> -- sleep 60
perf record -g -a -- sleep 10
# 采集 Off-CPU 数据
perf record -e sched:sched_stat_sleep -g -p <pid> -- sleep 60

3.3 perf report 分析#

perf report
# 输出调用图
perf report --stdio
perf report --stdio --sort symbol
# 过滤特定进程
perf report --stdio --pid=<pid>

3.4 perf 生成火焰图#

perf record -F 99 -g -p <pid> -- sleep 60
# 2. 折叠调用栈
perf script | stackcollapse-perf.pl > out.perf-folded
flamegraph.pl out.perf-folded > flamegraph.svg
# 使用 Brendan Gregg 的 FlameGraph 工具
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > flamegraph.svg

3.5 perf 与持续性能分析的关系#

维度perf(按需)持续性能分析
采集方式手动执行 perf recordAgent 常驻后台
采集频率短期高频(999 Hz)长期低频(19-99 Hz)
数据存储本地文件远程存储(S3/GCS)
可视化手动生成 SVGWeb UI 实时查看
历史对比需要手动保存自动保存,支持差分对比
适用场景性能调优、故障排查性能回归检测、趋势分析

四、eBPF 采样机制#

4.1 为什么持续性能分析选择 eBPF?#

传统的 perf 采样需要挂载到目标进程,且依赖 perf_event_open 系统调用。eBPF 提供了更灵活的采样机制:

graph TB subgraph 传统perf["传统 perf 采样"] PERF_OPEN["perf_event_open()"] PERF_MMAP["mmap 共享内存<br/>环形缓冲区"] PERF_READ["用户态读取<br/>调用栈数据"] end subgraph eBPF采样["eBPF 采样"] BPF_PROG["eBPF 程序<br/>挂载到 perf_event"] BPF_MAP["eBPF Map<br/>聚合调用栈"] BPF_READ["用户态读取<br/>聚合结果"] end PERF_OPEN --> PERF_MMAP --> PERF_READ BPF_PROG --> BPF_MAP --> BPF_READ style 传统perf fill:#fff3e0,stroke:#e65100 style eBPF采样 fill:#e0f2f1,stroke:#00695c

4.2 eBPF 采样的优势#

优势说明
内核态聚合eBPF 程序在内核态完成调用栈聚合,减少用户态/内核态切换
零侵入不需要修改目标进程,不需要注入 Agent
低开销内核态聚合后只传输统计结果,而非原始调用栈
多语言支持不依赖语言运行时,适用于所有编译型语言
BTF 支持利用内核 BTF 信息直接解析内核函数符号

4.3 eBPF 采样工作流程#

# 1. 加载 eBPF 程序到内核
# 3. 每次采样时,eBPF 程序:
# b. 采集用户态和内核态调用栈
# 4. 用户态定期读取 Map 数据

五、持续性能分析工具#

5.1 Parca 架构深入#

Parca 是一个开源的持续性能分析平台,由 Polar Signals(现 Coroot)开发。它的核心设计理念是”零侵入 eBPF 采集 + 远程符号解析 + 对象存储后端”。

graph TB subgraph Agent[" Parca Agent"] PA_EBPF["eBPF 采集器<br/>perf_event 挂载"] PA_SYM["符号解析器<br/>运行时 + 后置"] PA_COMP["压缩器<br/>zstd 压缩"] PA_UPLOAD["上传器<br/>gRPC 流式上传"] end subgraph Server[" Parca Server"] PA_API["API Server<br/>gRPC + HTTP"] PA_QUERY["查询引擎<br/>Profile 查询"] PA_STORE["存储引擎<br/>Parquet 列存"] PA_OBJ["对象存储<br/>S3/GCS/Local"] end subgraph UI[" 可视化"] PUI["Parca UI<br/>Grafana 插件"] end PA_EBPF --> PA_SYM --> PA_COMP --> PA_UPLOAD PA_UPLOAD -->|"gRPC"| PA_API PA_API --> PA_QUERY PA_API --> PA_STORE PA_STORE --> PA_OBJ PUI --> PA_API style Agent fill:#e3f2fd,stroke:#1565c0 style Server fill:#e0f2f1,stroke:#00695c style UI fill:#fff3e0,stroke:#e65100

Parca 的关键设计决策:

设计决策选择原因
采集方式eBPF零侵入、全语言支持
存储格式Parquet 列存高压缩比、列式查询高效
符号解析运行时 + 后置运行时快速解析,后置补充调试信息
传输协议gRPC 流式低延迟、高效传输
元数据Kubernetes Label自动关联 Pod/Service 信息

5.2 Pyroscope 架构深入#

Pyroscope 是 Grafana 生态的持续性能分析工具,与 Grafana 深度集成:

graph TB subgraph SDK集成[" SDK / Agent"] PY_SDK["语言 SDK<br/>Go/Python/Java/.NET"] PY_AGENT["Pyroscope Agent<br/>Sidecar 模式"] PY_JAVA["Java Agent<br/>JVM Instrumentation"] end subgraph Server[" Pyroscope Server"] PY_API["API Server<br/>HTTP + gRPC"] PY_INGEST["Ingestor<br/>数据摄入"] PY_STORE["存储引擎<br/>本地 + 对象存储"] PY_QUERY["查询引擎<br/>Flamegraph API"] end subgraph Grafana生态[" Grafana 集成"] PY_GF["Grafana 数据源<br/>原生 Profile 面板"] PY_EXPLORE["Grafana Explore<br/>火焰图查看"] end PY_SDK --> PY_API PY_AGENT --> PY_API PY_JAVA --> PY_API PY_API --> PY_INGEST --> PY_STORE PY_QUERY --> PY_STORE PY_GF --> PY_QUERY PY_EXPLORE --> PY_GF style SDK集成 fill:#e8eaf6,stroke:#283593 style Server fill:#e0f2f1,stroke:#00695c style Grafana生态 fill:#fff3e0,stroke:#e65100

5.3 工具对比#

维度ParcaPyroscope
采集方式eBPF(零侵入)SDK + Agent
语言支持所有语言(eBPF)Go、Python、Java、Node.js、.NET
存储对象存储(S3/GCS)本地 + 对象存储
与 Grafana 集成插件原生数据源
开源
商业版Parca CloudGrafana Cloud Profiles
存储格式Parquet 列存自定义格式
符号解析运行时 + 后置运行时
多租户

5.4 持续性能分析 vs 按需性能分析#

维度持续性能分析按需性能分析(perf)
采集方式Agent 常驻后台手动执行 perf record
采集频率低频持续(19-99 Hz)高频短期(999-4999 Hz)
数据覆盖7-30 天历史数据仅当前采集窗口
性能回归检测差分对比需手动对比
故障回溯事后查看历史 Profile故障时未采集则无数据
运维成本中(需部署 Agent + Server)低(直接使用 perf)
适用场景生产环境持续监控开发环境性能调优
Note

持续性能分析不是要取代按需性能分析。两者是互补的:持续性能分析用于发现性能回归和长期趋势,按需性能分析用于深入分析具体问题。最佳实践是先通过持续性能分析发现热点,再用 perf 深入分析。

5.5 Go 应用集成 Pyroscope#

import "github.com/grafana/pyroscope-go"
func main() {
// 启动 Pyroscope profiling
pyroscope.Start(pyroscope.Config{
ApplicationName: "order-service",
ServerAddress: "http://pyroscope:4040",
Logger: pyroscope.StandardLogger,
Tags: map[string]string{"region": "us-east-1"},
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileMemObjects,
pyroscope.ProfileMemInuse,
pyroscope.ProfileGoroutines,
pyroscope.ProfileBlock,
pyroscope.ProfileMutex,
},
})
// 应用逻辑...
}

5.6 Java 应用集成 Pyroscope#

# 使用 Java Agent(零代码修改)
java -javaagent:pyroscope.jar \
-Dpyroscope.application.name=order-service \
-Dpyroscope.server.address=http://pyroscope:4040 \
-jar my-app.jar

六、内存性能分析#

6.1 内存 Profile 类型#

CPU Profile 告诉你”哪个函数在消耗 CPU”,内存 Profile 则告诉你”哪个函数在分配内存”:

Profile 类型观测对象Go pprof 名称用途
堆内存分配当前存活对象alloc_objects / alloc_space找到内存分配热点
堆内存使用当前在用内存inuse_objects / inuse_space找到内存占用热点
栈内存分配栈上分配通常不需要关注
GC 压力GC 频率和耗时gc_pause找到 GC 压力来源

6.2 内存火焰图#

内存火焰图与 CPU 火焰图结构相同,但宽度代表内存分配量而非 CPU 时间:

perf record -e mem-loads -g -p <pid> -- sleep 60
# 使用 bpftrace 采集 malloc 调用
bpftrace -e '
uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc /pid == $1/ {
@stack[ustack] = sum(arg0);
}
'

6.3 内存泄漏诊断流程#

graph TB START["内存持续增长"] --> BASELINE["采集基线内存 Profile"] BASELINE --> WAIT["等待 30 分钟"] WAIT --> SECOND["采集第二次内存 Profile"] SECOND --> DIFF["差分对比<br/>inuse_space 差异"] DIFF --> HOTSPOT["定位增长最快的函数"] HOTSPOT --> FIX["修复内存泄漏"] FIX --> VERIFY["验证内存稳定"] style START fill:#ffcdd2,stroke:#c62828 style HOTSPOT fill:#fff3e0,stroke:#e65100 style VERIFY fill:#c8e6c9,stroke:#2e7d32

七、Go pprof 集成#

7.1 pprof 基础#

Go 语言内置了 runtime/pprofnet/http/pprof,是 Go 应用性能分析的标准工具:

import (
"net/http"
_ "net/http/pprof" // 自动注册 /debug/pprof 路由
)
func main() {
// 启动 pprof HTTP 端点
go func() {
http.ListenAndServe(":6060", nil)
}()
// 应用逻辑...
}

7.2 pprof 采集方式#

curl -o cpu.prof http://localhost:6060/debug/pprof/profile?seconds=30
# 采集堆内存 Profile
curl -o heap.prof http://localhost:6060/debug/pprof/heap
# 采集 goroutine Profile
curl -o goroutine.prof http://localhost:6060/debug/pprof/goroutine
# 采集阻塞 Profile
curl -o block.prof http://localhost:6060/debug/pprof/block
# 采集锁竞争 Profile
curl -o mutex.prof http://localhost:6060/debug/pprof/mutex

7.3 pprof 分析方式#

# 交互式分析(命令行)
go tool pprof cpu.prof
# (pprof) top 10 — 显示 Top 10 热点函数
# (pprof) web — 生成调用图(需要 graphviz)
# (pprof) list func — 查看函数级别的性能数据
# Web UI 分析
go tool pprof -http=:8080 cpu.prof
# 差分对比
go tool pprof -base cpu_before.prof cpu_after.prof

7.4 pprof 与 Pyroscope 集成#

Pyroscope 的 Go SDK 底层使用 runtime/pprof 采集数据,但将数据持续发送到 Pyroscope Server 而非本地文件:

// Pyroscope 内部使用 pprof 的方式
import (
"runtime/pprof"
"time"
)
func collectAndSend() {
for range time.Tick(10 * time.Second) {
// 采集 CPU Profile
var cpuBuf bytes.Buffer
pprof.StartCPUProfile(&cpuBuf)
time.Sleep(10 * time.Second)
pprof.StopCPUProfile()
// 发送到 Pyroscope Server
sendToPyroscope(cpuBuf.Bytes())
}
}
维度pprof(本地)Pyroscope(持续)
采集方式手动触发自动持续
数据存储本地文件远程 Server
历史对比需手动保存文件自动保存,Web UI 差分
多实例每个实例单独采集统一聚合
适用场景开发调试生产监控

八、符号解析#

8.1 为什么需要符号解析?#

性能分析采集的是内存地址,不是函数名。符号解析(Symbolization)将地址映射为函数名和源码位置:

地址 0x7f3a2b1c3d40 → main.processOrder (order_service.go:142)
地址 0x7f3a2b1c4e50 → database.Query (db.go:87)

8.2 符号解析方式#

方式时机优点缺点
运行时解析采集时准确需要调试符号
后置解析查询时不影响采集需要保存镜像/符号表
eBPF BTF采集时内核态直接解析仅限内核函数

8.3 Go 符号解析#

Go 二进制默认包含符号信息,无需额外配置:

# 编译时保留符号信息
go build -o app .
# 验证符号信息
go tool objdump -s "main." app

8.4 C/C++ 符号解析#

# 编译时添加调试符号
gcc -g -O2 -o app app.c
# 或使用 DWARF 调试信息
gcc -gdwarf-4 -O2 -o app app.c
# strip 后的符号表需要单独保存
objcopy --only-keep-debug app app.debug
strip -s app
objcopy --add-gnu-debuglink=app.debug app

九、持续性能分析的价值#

9.1 与三大信号的协同#

graph TB METRIC["指标: P99 延迟 2s"] --> TRACE["追踪: 定位到 order-service"] TRACE --> PROFILE["性能分析: processOrder 函数<br/>CPU 热点: JSON 序列化"] PROFILE --> FIX["修复: 更换 JSON 库<br/>P99 降到 200ms"] style METRIC fill:#e3f2fd,stroke:#1565c0 style TRACE fill:#e8f5e9,stroke:#2e7d32 style PROFILE fill:#fff3e0,stroke:#e65100 style FIX fill:#c8e6c9,stroke:#2e7d32
场景指标发现追踪定位性能分析深入
CPU 热点CPU 使用率 80%请求在 A 服务慢A 服务的 json.Marshal 消耗 60% CPU
内存泄漏内存持续增长请求在 B 服务慢B 服务的 cache.Set 导致堆增长
锁竞争延迟高但 CPU 低请求在 C 服务等待C 服务的 mutex.Lock 等待 80% 时间
GC 停顿P99 延迟飙升间歇性慢请求GC 耗时 50ms,堆对象 10M

9.2 回归检测#

持续性能分析可以检测性能回归——当代码变更导致性能下降时,火焰图的差分对比可以直观地显示变化:

优化前: json.Marshal 占 60% CPU
优化后: json.Marshal 占 30% CPU, sonic.Marshal 占 10% CPU
差分: json.Marshal -30%, sonic.Marshal +10%, 总 CPU -20%

十、生产部署考量#

10.1 部署架构选择#

架构适用场景优点缺点
Agent + ServerKubernetes 集群集中管理、统一存储需要额外部署 Server
Agent + SaaS快速启动无需运维 Server数据离开集群、成本高
Agent-only + 本地存储单机/小规模简单无集中管理

10.2 资源规划#

# Parca Agent 资源配置(每个节点)
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# Parca Server 资源配置(根据规模调整)
resources:
requests:
cpu: "2"
memory: 4Gi
limits:
cpu: "4"
memory: 8Gi
规模Agent 数量Server CPUServer 内存存储/月
小型(< 50 节点)502 核4 GiB50 GiB
中型(50-200 节点)2004 核16 GiB200 GiB
大型(> 200 节点)200+8 核32 GiB1 TiB+

10.3 采集策略#

# Parca Agent 采集配置
scrape_configs:
- job_name: "kubernetes-pods"
scrape_interval: 10s # 采集间隔
profiling_config:
cpu:
enabled: true
sample_rate: 19 # 19 Hz(低开销)
memory:
enabled: true
sample_rate: 19
采集频率CPU 开销存储/月(100 节点)适用场景
19 Hz~0.1%~50 GiB生产环境(默认)
99 Hz~0.5%~200 GiB性能敏感服务
自适应动态动态成本优化

10.4 安全考量#

# Parca Agent 需要的权限(Kubernetes)
# 1. 访问 /proc 和 /sys(读取进程信息)
# 2. CAP_BPF 或 CAP_SYS_ADMIN(eBPF 采集)
# 3. 访问容器运行时(Docker/containerd)
# 最小权限配置
securityContext:
capabilities:
add: ["CAP_BPF", "CAP_SYS_PTRACE"]
readOnlyRootFilesystem: true
runAsNonRoot: false # eBPF 需要 root
Warning

持续性能分析 Agent 需要特权权限才能采集调用栈。在多租户环境中,务必将 Agent 部署在独立的命名空间,并限制其 RBAC 权限。不要让普通用户有权查看其他租户的 Profile 数据。

十一、动手实践:搭建持续性能分析#

11.1 部署 Pyroscope#

# Pyroscope Docker Compose
services:
pyroscope:
image: grafana/pyroscope:latest
ports:
- "4040:4040"
volumes:
- pyroscope-data:/var/lib/pyroscope
environment:
- PYROSCOPE_LOG_LEVEL=info
# 应用集成
app:
environment:
- PYROSCOPE_APPLICATION_NAME=order-service
- PYROSCOPE_SERVER_ADDRESS=http://pyroscope:4040
docker compose up -d pyroscope
curl http://localhost:4040

11.2 集成到应用#

// Go 应用集成
pyroscope.Start(pyroscope.Config{
ApplicationName: "demo-api",
ServerAddress: "http://pyroscope:4040",
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileMemInuse,
pyroscope.ProfileGoroutines,
},
})

11.3 在 Grafana 中查看#

# 打开 Grafana Explore
open http://localhost:3000/explore
# 选择 Pyroscope 数据源
# 查看火焰图

11.4 验证清单#

检查项验证方式预期结果
Pyroscope 接收数据UI 查看能看到火焰图
CPU Profile查看 CPU 火焰图函数名正确显示
内存 Profile查看内存火焰图分配热点可见
与追踪关联从追踪跳转到火焰图时间对齐

十二、本章小结#

上一章理解了OpenTelemetry 架构。 这一章把可观测性的第四大支柱——持续性能分析的核心问题讲透了。

主题核心要点关键词
采样原理通过定期”拍照”记录调用栈,用统计学方法估算性能热点。采样原理
火焰图阅读看宽度不看高度,从底部向上看,寻找”平台”结构,忽略小栈帧。火焰图阅读
CPU 瓶颈识别计算密集、锁竞争、系统调用、GC 压力、调度延迟五种典型模式。CPU 瓶颈识别
perf 工具Linux 内核自带的性能分析工具,是持续性能分析的基础设施。perf 工具
eBPF 采样内核态聚合、零侵入、低开销,是持续性能分析的首选采集方式。eBPF 采样
Parca vs PyroscopeParca 用 eBPF 零侵入 + Parquet 存储,Pyroscope 用 SDK 集成 + Grafana 原生。Parca vs Pyroscope
内存性能分析堆内存分配/使用、GC 压力,差分对比诊断内存泄漏。内存性能分析
Go pprofGo 内置性能分析工具,Pyroscope SDK 底层使用 pprof 采集。Go pprof
符号解析将内存地址映射为函数名,是性能分析的前提。符号解析
生产部署资源规划、采集策略、安全考量,确保持续性能分析在生产环境稳定运行。生产部署

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

持续性能分析:第四大支柱
https://blog.souloss.com/posts/observability/continuous-profiling/
作者
Souloss
发布于
2025-08-25
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时