Go Wiki: CustomPprofProfiles
最初發佈於 https://rakyll.org/custom-profiles/。
Go 開箱即用地提供了幾個 pprof profile,用於從 Go 程式收集分析資料。
由 runtime/pprof 包提供的內建 profile
- profile:CPU profile 確定程式在積極消耗 CPU 週期時(而非睡眠或等待 I/O 時)將時間花在了哪裡。
- heap:Heap profile 報告當前活動的分配;用於監控當前記憶體使用情況或檢查記憶體洩漏。
- threadcreate:Thread creation profile 報告導致建立新 OS 執行緒的程式部分。
- goroutine:Goroutine profile 報告所有當前 goroutine 的堆疊跟蹤。
- block:Block profile 顯示 goroutine 在等待同步原語(包括定時器通道)時被阻塞的位置。Block profile 預設未啟用;使用 runtime.SetBlockProfileRate 來啟用它。
- mutex:Mutex profile 報告鎖的爭用。當您認為 CPU 未被充分利用是由於互斥鎖爭用時,請使用此 profile。Mutex profile 預設未啟用,請參閱 runtime.SetMutexProfileFraction 來啟用。
除了內建 profile,runtime/pprof 包還允許您匯出自定義 profile,並對程式碼進行儀器化以記錄對該 profile 有貢獻的執行堆疊。
想象一下我們有一個 blob 伺服器,我們正在為其編寫一個 Go 客戶端。我們的使用者希望能夠對客戶端上的已開啟 blob 進行分析。我們可以建立一個 profile 並記錄開啟和關閉 blob 的事件,這樣使用者就可以隨時知道有多少 blob 已開啟。
這是一個允許您開啟一些 blob 的 blobstore 包。我們將建立一個新的自定義 profile 並開始記錄導致 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 時,我們需要從 profile 中移除與當前 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 profile 資料,並使用我們日常的 pprof 工具來檢查和視覺化它們。
讓我們編寫一個開啟一些 blob 的小型 main 程式。
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 tool 讀取和視覺化 profile 資料。
$ go tool pprof https://: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 的一部分。