Golang对程序进行trace

勿忘初心2018-10-26 10:04

此文已由作者闫明授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


Golang最核心的就是go routine,在程序运行过程中你可能想知道go routine是如何被调度的?或者使用大量go routine时程序的性能并没有达到预期,如何对这些问题进行定位呢?Golang自带了trace工具,可以实现对程序运行过程中的指标进行监控。比如

  • goroutine的创建,开始和结束

  • goroutine产生的事件(系统调用、channel、锁)

  • 网络IO

  • 系统调用

  • 垃圾回收

这些数据不会进行聚合或者采样,产生的全量数据可能会非常大,产生的文件通过go tool trace来进行查看。

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数据图。

view trace

  • 时间线

  • 内存堆栈分配

  • Goroutines

  • 操作系统线程

  • go runtime线程

  • goroutine和事件

Blocking Profiles

 上面图片展示了main的go routine花了12.08微妙等待另一个go routine发送数据。在很多goroutine并发的时候这个图可以很好的展示进程的阻塞情况。 其他类型(同步、系统调用)产生的阻塞也可以一目了然。

使用trace进行程序优化

trace工具可以对并发或资源竞争问题更有效的展示,方便进行问题调试,但是这个工具不适合那种高cpu负载的代码片段分析,这种情况使用go tool pprof会更适合。


网易云免费体验馆,0成本体验20+款云产品! 

更多网易技术、产品、运营经验分享请点击


相关文章:
【推荐】 如何选择SSL 证书服务
【推荐】 行为式验证码的前景