函数名全是[unknown]是因为缺少调试符号和帧指针信息;需编译时加-g -fno-omit-frame-pointer,确认二进制未strip,并检查perf权限与符号路径配置。

perf record 采样时为什么函数名全是 [unknown]?
这是火焰图分析中最常见的拦路虎,本质是符号信息缺失。Kratos 服务编译时若没加 -g 和 -fno-omit-frame-pointer,perf 就无法还原调用栈中的函数名,只能显示地址或占位符。
实操建议:
- Go 编译需显式启用调试信息:
go build -gcflags="-N -l" -ldflags="-s -w" -o app ./cmd/app(-N -l禁用内联和优化,保留行号和符号) - 确认二进制未被 strip:
file app输出应含not stripped;若为stripped,重编译 - Kratos 项目若用
make build,检查 Makefile 中是否覆盖了GOFLAGS,避免构建脚本静默丢掉调试信息 - 容器内采样时,确保镜像中包含未 strip 的二进制,且
/proc/sys/kernel/perf_event_paranoid已设为-1(否则 perf 权限不足)
kratos service 启动后怎么精准抓取 CPU 热点?
不能等服务“看起来卡”再动手——那时可能已错过关键窗口。Kratos 默认启用了 gRPC/HTTP 多路复用和中间件链,热点常藏在 middleware.Tracing、transport/http.(*Server).ServeHTTP 或 data.repo.GetByID 这类封装层下。
实操建议:
- 用
pgrep定位进程 PID:pgrep -f "cmd/app",避免采样到 shell 或 supervisord - 限定采样时长与频率:
perf record -F 99 -g -p $(pgrep -f "cmd/app") -- sleep 20(20 秒足够捕获典型请求周期) - 若怀疑某类接口拖慢整体,先用 Kratos 自带的
/debug/pprof/profile快速验证:curl "http://localhost:8000/debug/pprof/profile?seconds=30" > cpu.pprof,再用go tool pprof cpu.pprof交互式查看 top 函数 - 注意:不要在高负载压测中途直接
perf record -a全系统采样,容易淹没 Kratos 进程本身的调用特征
生成的火焰图里,kratos/middleware 和 proto 生成代码占比异常高,正常吗?
正常,但需分情况判断。Kratos 的强约束架构决定了大量逻辑会经过标准中间件链(如 recovery、tracing、logging),而 proto 生成的 Unmarshal / Marshal 在高 QPS 下天然开销显著。
关键看宽度分布:
- 若
middleware.Tracing宽度远超业务service.UserSvc.Create,说明链路追踪注入/上报有瓶颈,检查 Jaeger 客户端配置是否同步阻塞,或是否启用了冗余 tag - 若
proto.Unmarshal占比突增,优先确认是否误传了超大 payload(如 base64 图片字段未做 size 限制),而非急着换序列化方案 - 真正危险的信号是:
runtime.mallocgc或runtime.scanobject出现在顶部宽矩形中——这指向内存分配压力,需结合pprof/heap进一步确认 - Kratos 的
data层若频繁调用sqlx.Get但火焰图中database/sql.(*DB).conn长时间阻塞,大概率是连接池MaxOpenConns设置过小或 DB 响应变慢
为什么用 flamegraph.pl 生成 SVG 后,浏览器打开一片空白?
不是火焰图坏了,而是输入数据格式不合法。FlameGraph 脚本对输入极其敏感,任何空行、乱码、非折叠格式都会导致输出为空 SVG。
排查步骤:
- 检查
out.perf-folded是否真有内容:head -n 5 out.perf-folded应看到类似main;server.Run;grpc.NewServer;grpc.(*Server).Serve 127的行 - 确认
stackcollapse-perf.pl路径正确且可执行:perl ~/FlameGraph/stackcollapse-perf.pl --help不报错 - perf script 输出是否含中文或特殊字符?某些 locale 下会混入不可见控制符,加
LC_ALL=C perf script | ...强制 ASCII - 最简验证法:手动造一行测试数据
echo "a;b;c 10" > test.folded && ~/FlameGraph/flamegraph.pl test.folded > test.svg,能打开则说明环境 OK,问题出在原始采样
火焰图本身不解决性能问题,它只诚实反映「谁在占用 CPU 时间」。Kratos 项目里最容易被忽略的是中间件顺序和 proto 编解码的隐式开销——它们不会报错,但会在高并发下把 10ms 的业务逻辑拖成 150ms,而火焰图是唯一能让你看清这一层薄冰的工具。











