简介

​go tool trace 是 Go 语言提供的一个强大的性能分析工具,它能够对程序运行时的行为进行可视化追踪,帮助开发者深入分析和诊断 GC(垃圾回收)、Goroutine 调度、系统调用阻塞等问题。

使用方法

首先,创建一个简单的 Go 程序 main.go 来生成 trace 文件:

package main

import (
	"os"
	"runtime/trace"
)

func main() {
	f, _ := os.Create("trace.out")

	trace.Start(f)
	defer trace.Stop()

	for i := 0; i < 10000; i++ {
		_ = make([]byte, 1<<20)
	}
}

运行此程序,使用命令 go run main.go,将生成一个 trace.out 文件。随后,通过命令 go tool trace trace.out 启动追踪文件的可视化分析。

在这里插入图片描述在这里插入图片描述

功能概览

go tool trace 提供了多种视图以帮助分析程序性能,包括:

  • View trace:基础时间线视图,展示程序执行的各个阶段。
  • Goroutine analysis:Goroutine 分析,查看程序中的 Goroutine 分布和状态。
  • Network blocking profile:网络阻塞概况,分析网络操作对性能的影响。
  • Synchronization blocking profile:同步阻塞概况,分析同步操作导致的阻塞。
  • Syscall blocking profile:系统调用阻塞概况,分析系统调用对性能的影响。
  • Scheduler latency profile:调度延迟概况,分析调度器的性能。
  • User defined tasks & regions:用户自定义任务和区域,为特定的代码段添加标记。
  • Minimum mutator utilization:最低 Mutator 利用率。
查看 View trace

在这里插入图片描述

上图看着密密麻麻的,点击右上角 ?可以查看使用导航

在这里插入图片描述

点击键盘 w 进行放大后如下图

视图详解

View trace 视图提供了一个宏观的视角,显示了程序执行的时间线、内存分配、Goroutine 状态、OS 线程和虚拟处理器 P 的活动情况。

  1. 时间线:展示执行的时间单元,可以调整时间区间以查看不同粒度的信息。
  2. 堆:显示内存的分配和释放情况。
  3. 协程:展示不同状态下的 Goroutine 数量,包括 GC 等待、可运行和运行中状态。
  4. OS 线程:展示线程的活动状态,包括 Syscall 和运行中状态。
  5. 虚拟处理器 P:显示虚拟处理器的活动,通常数量与系统内核数一致。
  6. 协程和事件:展示每个虚拟处理器上的 Goroutine 活动和事件关联。

通过点击 flow events,可以查看事件的详细流,这有助于理解程序执行的具体流程。

点击特定的 Goroutine,可以查看其详细信息

在这里插入图片描述

字段解释:

  • Start:开始时间。
  • Wall Duration:持续时间。
  • Self Time:自身执行时间。
  • Start Stack Trace & End Stack Trace:开始和结束时的堆栈信息。
  • Incoming & Outgoing flow:输入和输出流。
  • Preceding & Following events:前序和后继事件。
  • All connected:所有相关联的事件。
深入分析系统耗时:Scheduler Latency Profile

​ 通过访问 Scheduler Latency Profile,开发者可以洞察系统的调度延迟情况。该页面提供了一个图形化界面,直观地展示了系统在不同时间段的调度效率。

在这里插入图片描述

系统调用耗时分析:Syscall Blocking Profile

​ 进一步地,通过查看 [Syscall Blocking Profile],开发者能够识别出系统调用过程中的潜在阻塞点。这对于优化系统性能和排查问题至关重要。

在这里插入图片描述

在线环境监控实践

​ 在生产环境中,我们推荐使用 net/http/pprof 包来实现监控。此包自动注册了多个监控路由,使得性能分析变得简单快捷。

示例代码

package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
)

func index(w http.ResponseWriter, r *http.Request) {
	for n := 1; n < 100000; n++ {
		_ = make([]byte, 1<<20)
	}

	fmt.Fprintln(w, "Hello World")
}

func main() {
	http.HandleFunc("/", index)
	http.ListenAndServe(":8082", nil)
}

​ 注册路由:

func init() {
	http.HandleFunc("/debug/pprof/", Index)
	http.HandleFunc("/debug/pprof/cmdline", Cmdline)
	http.HandleFunc("/debug/pprof/profile", Profile)
	http.HandleFunc("/debug/pprof/symbol", Symbol)
	http.HandleFunc("/debug/pprof/trace", Trace)
}

通过以下命令,开发者可以对线上服务进行实时监控:

  • 使用 curl 获取追踪数据:

    curl http://127.0.0.1:8082/debug/pprof/trace?seconds=20 > trace.out
    

    其中 seconds=20 指定了监控的持续时间。

  • 使用 go tool trace 分析追踪文件:

    go tool trace trace.out
    
参考资源
  1. 深入理解 Go 语言的跟踪剖析工具
结语

go tool trace 是 Go 开发者进行性能分析的得力助手。通过上述介绍,我们可以看到它如何帮助我们从不同角度审视程序的运行情况,从而优化性能和解决潜在问题。掌握这一工具,将使你在 Go 语言的性能调优之路上更加得心应手。

Logo

欢迎加入西安开发者社区!我们致力于为西安地区的开发者提供学习、合作和成长的机会。参与我们的活动,与专家分享最新技术趋势,解决挑战,探索创新。加入我们,共同打造技术社区!

更多推荐