Home / PostsPost

Goland pprof 火焰图

嘟噜聪2023/03/02 15:35:32 [Golang] [pprof] [火焰图] [性能分析] [工具] [go tools] 1232人已阅

简介 > Golang的pprof是一个性能分析工具,可以用于分析程序的CPU、内存使用情况等,可以帮助我们快速定位代码中的性能瓶颈。![](http://source.qiniu.cnd.nsin

Golang的pprof是一个性能分析工具,可以用于分析程序的CPU、内存使用情况等,可以帮助我们快速定位代码中的性能瓶颈。

pprof提供了两种类型的性能分析:CPU profileMemory profile

CPU profile

通过捕捉一段时间内的CPU使用情况来生成CPU profile。我们可以使用go tool pprof命令对生成的profile文件进行分析。

生成CPU profile的步骤如下:

import (
    "log"
    "os"
    "runtime/pprof"
)

func main() {
    f, err := os.Create("cpuprofile")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    if err := pprof.StartCPUProfile(f); err != nil {
        log.Fatal(err)
    }
    defer pprof.StopCPUProfile()

    // 程序代码

}

在程序运行过程中,pprof会将CPU的使用情况记录到cpuprofile文件中。当我们需要分析程序性能时,可以使用以下命令:

$ go tool pprof -http=:8080 cpuprofile

这个命令会启动一个Web服务,我们可以在浏览器中访问http://localhost:8080来进行可视化分析。

Memory profile

生成Memory profile的步骤如下:

import (
    "log"
    "os"
    "runtime/pprof"
)

func main() {
    f, err := os.Create("memprofile")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    if err := pprof.WriteHeapProfile(f); err != nil {
        log.Fatal(err)
    }

    // 程序代码
}

在程序运行过程中,pprof会将内存的分配情况记录到memprofile文件中。当我们需要分析程序内存使用时,可以使用以下命令:

$ go tool pprof -http=:8080 memprofile

这个命令同样会启动一个Web服务,我们可以在浏览器中访问http://localhost:8080来进行可视化分析。

除了命令行工具外,pprof还提供了一些API供程序中使用,比如可以通过调用runtime/pprof包中的一些函数来生成profile文件,也可以通过调用http/pprof包中的API来实现Web接口,方便远程获取程序的性能数据。

runtime/pprof部分功能介绍

pprof是Golang标准库中的一个性能分析工具,提供了很多API供程序使用,方便对程序的性能进行分析和优化。

  • func StartCPUProfile(w io.Writer) error StartCPUProfile用来开始CPU的性能分析,将CPU的性能数据写入一个指定的文件中。参数w是一个io.Writer接口类型的变量,可以指定将CPU性能数据写入到哪个文件中。

  • func StopCPUProfile() StopCPUProfile用来停止CPU的性能分析,并将收集到的性能数据写入到上面指定的文件中。

  • func Lookup(symbol string) *Profile Lookup用来查找指定的性能分析数据,可以通过指定符号(symbol)的方式查找。

  • func WriteHeapProfile(w io.Writer) error WriteHeapProfile用来写入堆内存分析的性能数据,将收集到的数据写入一个指定的文件中。

  • func WriteProfile(p *Profile, name string) error WriteProfile用来将指定的性能分析数据写入到指定的文件中。

这些API可以方便地对程序进行性能分析,可以通过手动触发分析数据的收集,并将分析数据写入文件中,然后通过pprof工具进行分析。此外,pprof还提供了一些其他的API,如通过HTTP接口获取性能分析数据等,方便程序进行集成。

通过HTTP接口获取数据

如果在 HTTP 服务中引用了 runtime/pprof 包,并启用了 pprof 收集器,那么你可以通过以下步骤来访问 pprof 数据:

  1. 在 HTTP 服务中注册 pprof 的 HTTP 处理函数,这个函数会将 pprof 数据暴露给外部请求:
import (
    "net/http"
    _ "net/http/pprof" // 导入 pprof 包,执行包初始化函数,注册 pprof 处理函数
)

func main() {
    // 注册 HTTP 路由处理函数
    http.HandleFunc("/", myHandler)

    // 注册 pprof 处理函数
    http.HandleFunc("/debug/pprof/", pprof.Index)

    // 启动 HTTP 服务
    http.ListenAndServe(":8080", nil)
}

上面代码中,我们通过 _ "net/http/pprof" 导入了 net/http/pprof 包,并通过 pprof.Index 函数注册了 pprof 的 HTTP 处理函数,将其绑定到了 /debug/pprof/ 路径上。

  1. 访问 pprof 数据

在浏览器中访问 http://localhost:8080/debug/pprof/ 即可进入 pprof 的 web 页面,浏览器会显示出所有可用的 pprof 数据类型,包括 heapgoroutinethreadcreateblockmutex 等。我们可以点击其中任意一个类型,然后通过相应的页面进行数据分析。

如果需要在程序代码中访问 pprof

可以使用 http/pprof 包提供的接口来访问 runtime/pprof 提供的性能分析数据。http/pprof 包默认会注册以下路由:

  • /debug/pprof/: 显示当前进程的所有性能分析数据链接。
  • /debug/pprof/cmdline: 显示进程启动命令行参数。
  • /debug/pprof/profile: 返回 CPU Profiling 数据。
  • /debug/pprof/heap: 返回堆内存分配数据。
  • /debug/pprof/block: 返回阻塞事件数据。
  • /debug/pprof/mutex: 返回互斥锁的竞争关系数据。

通过访问这些路由,就可以获取到相应的性能分析数据。例如,访问 /debug/pprof/profile 就可以获取到 CPU Profiling 数据。

同时,http/pprof 包也提供了一些方法来注册这些路由。例如,http/pprof 包提供了 http.HandleFunc 方法来注册处理 /debug/pprof/ 路由的回调函数。代码示例如下:

package main

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

func main() {
	// 启动 http 服务,注册 pprof 相关路由
	go func() {
		err := http.ListenAndServe(":8080", nil)
		if err != nil {
			panic(err)
		}
	}()

	// TODO: 启动你的应用服务
	// ...
}

上面的代码中,我们通过使用 _ "net/http/pprof" 的方式来注册了 http/pprof 包提供的路由。然后通过 http.ListenAndServe 方法来启动一个 http 服务,提供对性能分析数据的访问。这里我们没有指定处理函数,所以会使用 http.DefaultServeMux,即使用 http/pprof 包默认注册的处理函数。

这样,我们就可以通过访问 http://localhost:8080/debug/pprof/ 来获取当前进程的所有性能分析数据链接,以及访问其他的路由来获取相应的性能分析数据。

很赞哦! (9)

文章评论

点击排行

本栏推荐

站点信息

  • 微信公众号