Go Wiki:CustomPprofProfiles
最初發布於 https://rakyll.org/custom-profiles/。
Go 提供了多種 pprof 設定檔,可從 Go 程式收集設定檔資料。
runtime/pprof 套件提供的內建設定檔
- 剖析:CPU 剖析會判斷程式在積極消耗 CPU 週期時會花費時間在哪裡(與睡眠或等待 I/O 時相反)。
- 堆積:堆積剖析會報告目前存在的配置;用於監控目前的記憶體使用量或檢查記憶體外洩。
- 執行緒建立:執行緒建立剖析會報告程式中導致建立新的作業系統執行緒的部分。
- goroutine:Goroutine 剖析會報告所有目前 goroutine 的堆疊追蹤。
- 區塊:區塊剖析會顯示 goroutine 在等待同步原語(包括計時器頻道)時會區塊在哪裡。區塊剖析預設不會啟用;請使用 runtime.SetBlockProfileRate 來啟用。
- 互斥鎖:互斥鎖剖析會報告鎖定競爭。當您認為 CPU 未充分使用是因為互斥鎖競爭時,請使用這個剖析。互斥鎖剖析預設不會啟用,請參閱 runtime.SetMutexProfileFraction 來啟用。
除了內建剖析之外,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 的一部分。