如何利用Golang的Pprof工具分析Block Profile以排查Go程序卡顿问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1129个文字,预计阅读时间需要5分钟。
Block Profile默认不是开启的,而是默认采样率极低(1/1000),因此大部分轻量级阻塞根本不会被记录。不手动调整+runtime.SetBlockProfileRate,你看到的profile很可能是一片空白或严重失真。
实操建议:
- 在程序启动早期(比如
main函数开头)调用runtime.SetBlockProfileRate(1),让每次阻塞都记录——仅限调试环境,线上慎用 - 若担心性能开销,至少设为
100(即平均每 100 纳秒阻塞才记一次),比默认的1(单位是纳秒?错,是「每阻塞 1 微秒采样一次」,实际默认值是1e6,即 1 毫秒)更敏感 - 确认你的服务确实启用了 pprof HTTP handler,路径通常是
/debug/pprof/block,直接 curl 或浏览器访问该地址会触发一次快照 - 别只看单次快照:阻塞是瞬态现象,要持续压测 + 多次抓取,否则容易漏掉偶发长阻塞
看懂 block profile 输出里谁在等、等什么
拿到 curl http://localhost:6060/debug/pprof/block?seconds=30 > block.pb.gz 后,用 go tool pprof block.pb.gz 进入交互模式,top 显示的是「累计阻塞时间最长的调用栈」,不是 CPU 占用高——这点极易混淆。
本文共计1129个文字,预计阅读时间需要5分钟。
Block Profile默认不是开启的,而是默认采样率极低(1/1000),因此大部分轻量级阻塞根本不会被记录。不手动调整+runtime.SetBlockProfileRate,你看到的profile很可能是一片空白或严重失真。
实操建议:
- 在程序启动早期(比如
main函数开头)调用runtime.SetBlockProfileRate(1),让每次阻塞都记录——仅限调试环境,线上慎用 - 若担心性能开销,至少设为
100(即平均每 100 纳秒阻塞才记一次),比默认的1(单位是纳秒?错,是「每阻塞 1 微秒采样一次」,实际默认值是1e6,即 1 毫秒)更敏感 - 确认你的服务确实启用了 pprof HTTP handler,路径通常是
/debug/pprof/block,直接 curl 或浏览器访问该地址会触发一次快照 - 别只看单次快照:阻塞是瞬态现象,要持续压测 + 多次抓取,否则容易漏掉偶发长阻塞
看懂 block profile 输出里谁在等、等什么
拿到 curl http://localhost:6060/debug/pprof/block?seconds=30 > block.pb.gz 后,用 go tool pprof block.pb.gz 进入交互模式,top 显示的是「累计阻塞时间最长的调用栈」,不是 CPU 占用高——这点极易混淆。

