如何在不中断程序运行的情况下,实时查询活跃的Goroutine数量?
- 内容介绍
- 文章标签
- 相关推荐
本文共计971个文字,预计阅读时间需要4分钟。
它返回的是当前已启动、尚未退出的所有+
常见错误是把它当成“用户创建的 goroutine 数”。实际上它包含 runtime 内部协程,比如:netpoll 的监听 goroutine、timer 管理协程、GC 辅助协程等,通常稳定在 2–5 个。别一看到值是 7 就怀疑自己漏了 defer wg.Done()。
- 在 HTTP handler 中暴露监控端点时,直接
return fmt.Sprintf("%d", runtime.NumGoroutine())即可 - 不要在每个请求里都调用并打日志——日志 IO 成本远高于
NumGoroutine()本身 - 该值不是流式指标,无法告诉你 goroutine 在哪卡住,只适合做数量趋势观察
用 /debug/pprof/goroutine?debug=2 查看真实堆栈
runtime.NumGoroutine() 返回一个整数,而 /debug/pprof/goroutine?debug=2 返回的是全部 goroutine 的完整调用栈快照,两者语义不同。pprof 默认(?debug=1)会过滤掉大量 idle 的 runtime 协程;加 ?debug=2 才能看到更全的视图,但依然可能不包含刚创建还没被调度的 goroutine。
本文共计971个文字,预计阅读时间需要4分钟。
它返回的是当前已启动、尚未退出的所有+
常见错误是把它当成“用户创建的 goroutine 数”。实际上它包含 runtime 内部协程,比如:netpoll 的监听 goroutine、timer 管理协程、GC 辅助协程等,通常稳定在 2–5 个。别一看到值是 7 就怀疑自己漏了 defer wg.Done()。
- 在 HTTP handler 中暴露监控端点时,直接
return fmt.Sprintf("%d", runtime.NumGoroutine())即可 - 不要在每个请求里都调用并打日志——日志 IO 成本远高于
NumGoroutine()本身 - 该值不是流式指标,无法告诉你 goroutine 在哪卡住,只适合做数量趋势观察
用 /debug/pprof/goroutine?debug=2 查看真实堆栈
runtime.NumGoroutine() 返回一个整数,而 /debug/pprof/goroutine?debug=2 返回的是全部 goroutine 的完整调用栈快照,两者语义不同。pprof 默认(?debug=1)会过滤掉大量 idle 的 runtime 协程;加 ?debug=2 才能看到更全的视图,但依然可能不包含刚创建还没被调度的 goroutine。

