Go Wiki:CustomPprofProfiles

最初发表于 https://rakyll.org/custom-profiles/


Go 提供了几个开箱即用的 pprof 配置文件,用于从 Go 程序收集分析数据。

runtime/pprof 包提供的内置配置文件

除了内置配置文件外,runtime/pprof 包还允许您导出自定义配置文件,并对代码进行检测以记录有助于此配置文件的执行堆栈。

假设我们有一个 blob 服务器,并且我们正在为其编写一个 Go 客户端。我们的用户希望能够对客户端上打开的 blob 进行分析。我们可以创建一个配置文件并记录 blob 打开和关闭的事件,以便用户随时了解他们打开了多少个 blob。

这是一个允许您打开一些 blob 的 blobstore 包。我们将创建一个新的自定义配置文件,并开始记录有助于打开 blob 的执行堆栈

package blobstore

import "runtime/pprof"

var openBlobProfile = pprof.NewProfile("blobstore.Open")

// Open opens a blob, all opened blobs need
// to be closed when no longer in use.
func Open(name string) (*Blob, error) {
    blob := &Blob{name: name}
    // TODO: Initialize the blob...

    openBlobProfile.Add(blob, 2) // add the current execution stack to the profile
    return blob, nil
}

一旦用户想要关闭 blob,我们需要从配置文件中删除与当前 blob 关联的执行堆栈

// Close closes the blob and frees the
// underlying resources.
func (b *Blob) Close() error {
    // TODO: Free other resources.
    openBlobProfile.Remove(b)
    return nil
}

现在,从使用此包的程序中,我们应该能够检索 blobstore.Open 配置文件数据,并使用我们日常的 pprof 工具来检查和可视化它们。

让我们编写一个打开一些 blob 的小型主程序

package main

import (
    "fmt"
    "math/rand"
    "net/http"
    _ "net/http/pprof" // as a side effect, registers the pprof endpoints.
    "time"

    "myproject.org/blobstore"
)

func main() {
    for i := 0; i < 1000; i++ {
        name := fmt.Sprintf("task-blob-%d", i)
        go func() {
            b, err := blobstore.Open(name)
            if err != nil {
                // TODO: Handle error.
            }
            defer b.Close()

            // TODO: Perform some work, write to the blob.
        }()
    }
    http.ListenAndServe("localhost:8888", nil)
}

启动服务器,然后使用 go 工具读取和可视化配置文件数据

$ go tool pprof https://127.0.0.1:8888/debug/pprof/blobstore.Open
(pprof) top
Showing nodes accounting for 800, 100% of 800 total
      flat  flat%   sum%        cum   cum%
       800   100%   100%        800   100%  main.main.func1 /Users/jbd/src/hello/main.go

您将看到有 800 个打开的 blob,并且所有打开都来自 main.main.func1。在这个小示例中,没有更多内容可以查看,但在一个复杂的服务器中,您可以检查与打开的 blob 一起工作的最热点,并找出瓶颈或泄漏。


此内容是 Go Wiki 的一部分。