Go Wiki:CustomPprofProfiles

最初發布於 https://rakyll.org/custom-profiles/


Go 提供了多種 pprof 設定檔,可從 Go 程式收集設定檔資料。

runtime/pprof 套件提供的內建設定檔

除了內建剖析之外,runtime/pprof 套件可讓您匯出自訂剖析,並設定您的程式碼以記錄有助於此剖析的執行堆疊。

假設我們有一個 blob 伺服器,我們正在為它撰寫一個 Go 程式用戶端。我們的使用者希望能夠剖析用戶端上已開啟的 blob。我們可以建立一個剖析並記錄開啟和關閉 blob 的事件,這樣使用者就能隨時知道他們開啟了多少個 blob。

這裡有一個 blobstore 套件,可讓您開啟一些 blob。我們將建立一個新的自訂剖析,並開始記錄有助於開啟 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 的一部分。