此文已由作者闫明授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
Golang最核心的就是go routine,在程序运行过程中你可能想知道go routine是如何被调度的?或者使用大量go routine时程序的性能并没有达到预期,如何对这些问题进行定位呢?Golang自带了trace工具,可以实现对程序运行过程中的指标进行监控。比如
goroutine的创建,开始和结束
goroutine产生的事件(系统调用、channel、锁)
网络IO
系统调用
垃圾回收
这些数据不会进行聚合或者采样,产生的全量数据可能会非常大,产生的文件通过go tool trace来进行查看。
以最简单的hello world为例,使用trace要导入runtime/trace包
package mainimport ( "os" "runtime/trace")func main() { trace.Start(os.Stderr) defer trace.Stop() // create new channel of type int ch := make(chan int) // start new anonymous goroutine go func() { // send 42 to channel ch <- 42 }() // read from channel <-ch }
这个实例是通过无buffer的channel实现go routine的通信。go routine将数据写入channel后阻塞,直到主进程从channel中读取数据。
执行go run main.go 2>trace.out会将trace的数据重定向到trace.out文件,使用go tool trace trace.out来解析。执行后会运行一个http server,通过浏览器可以看到trace或者profile数据图。
时间线
内存堆栈分配
Goroutines
操作系统线程
go runtime线程
goroutine和事件
上面图片展示了main的go routine花了12.08微妙等待另一个go routine发送数据。在很多goroutine并发的时候这个图可以很好的展示进程的阻塞情况。 其他类型(同步、系统调用)产生的阻塞也可以一目了然。
trace工具可以对并发或资源竞争问题更有效的展示,方便进行问题调试,但是这个工具不适合那种高cpu负载的代码片段分析,这种情况使用go tool pprof会更适合。
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 如何选择SSL 证书服务
【推荐】 行为式验证码的前景