如何深入探究Golang中Goroutine阻塞的根源,全面解析Go语言Block Profile的奥秘?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1082个文字,预计阅读时间需要5分钟。
使用`Go`的`runtime/pprof`提供了`block profile`功能,但默认是关闭的,并且仅记录超过1ms的阻塞事件。请注意,这并不是记录所有事件。
- 启动时加
-blockprofile=block.out参数(仅限go run或二进制运行);更常用的是在代码里调用pprof.StartCPUProfile之类的方式——但 block profile 不支持 Start/Stop 控制,必须靠持续运行+信号触发或定时写入 - 服务类程序建议在 HTTP handler 中暴露
/debug/pprof/block(需导入_ "net/http/pprof"),然后用wget http://localhost:8080/debug/pprof/block?seconds=30抓取 30 秒内的阻塞事件 - 注意:
?seconds=1很可能抓不到数据——因为默认采样阈值是 1ms,而短时间低频阻塞容易被漏掉;建议至少 10 秒以上,且系统得有真实阻塞压力
看到 pprof 输出里全是 runtime.semasleep、runtime.notesleep 怎么办
这类函数名说明你正卡在底层同步原语上,不是业务逻辑问题,而是 goroutine 在等锁、channel、timer 或 sync.Cond。关键不是“它在哪睡”,而是“它为什么醒不了”。
本文共计1082个文字,预计阅读时间需要5分钟。
使用`Go`的`runtime/pprof`提供了`block profile`功能,但默认是关闭的,并且仅记录超过1ms的阻塞事件。请注意,这并不是记录所有事件。
- 启动时加
-blockprofile=block.out参数(仅限go run或二进制运行);更常用的是在代码里调用pprof.StartCPUProfile之类的方式——但 block profile 不支持 Start/Stop 控制,必须靠持续运行+信号触发或定时写入 - 服务类程序建议在 HTTP handler 中暴露
/debug/pprof/block(需导入_ "net/http/pprof"),然后用wget http://localhost:8080/debug/pprof/block?seconds=30抓取 30 秒内的阻塞事件 - 注意:
?seconds=1很可能抓不到数据——因为默认采样阈值是 1ms,而短时间低频阻塞容易被漏掉;建议至少 10 秒以上,且系统得有真实阻塞压力
看到 pprof 输出里全是 runtime.semasleep、runtime.notesleep 怎么办
这类函数名说明你正卡在底层同步原语上,不是业务逻辑问题,而是 goroutine 在等锁、channel、timer 或 sync.Cond。关键不是“它在哪睡”,而是“它为什么醒不了”。

