1 pprof簡介
golang代碼的性能監(jiān)控使用pprof包來做躬它。pprof有兩個包:
-
runtime/pprof
pprof的具體實(shí)現(xiàn),所有類型的代碼都可以使用妇菱。如果不是Web應(yīng)用程序晦墙,建議使用該包。 -
net/http/pprof
對runtime/pprof
包進(jìn)行簡單封裝挨务,并在http端口上暴露出來。適合Web應(yīng)用程序使用挥唠。
2 pprof監(jiān)控內(nèi)容
pprof監(jiān)控的內(nèi)容項(xiàng)目入下表所示仅叫。
類型 | 描述 | 備注 |
---|---|---|
allocs | 內(nèi)存分配情況的采樣信息 | 可以用瀏覽器打開,但可讀性不高 |
blocks | 阻塞操作情況的采樣信息 | 可以用瀏覽器打開已添,但可讀性不高 |
cmdline | 顯示程序啟動命令及參數(shù) | 可以用瀏覽器打開朝巫,但可讀性不高 |
goroutine | 當(dāng)前所有協(xié)程的堆棧信息 | 可以用瀏覽器打開鸿摇,但可讀性不高 |
heap | 堆上內(nèi)存使用情況的采樣信息 | 可以用瀏覽器打開,但可讀性不高 |
mutex | 鎖爭用情況的采樣信息 | 可以用瀏覽器打開劈猿,但可讀性不高 |
profile | CPU 占用情況的采樣信息 | 瀏覽器打開會下載文件 |
threadcreate | 系統(tǒng)線程創(chuàng)建情況的采樣信息 | 可以用瀏覽器打開拙吉,但可讀性不高 |
trace | 程序運(yùn)行跟蹤信息 | 瀏覽器打開會下載文件 |
3 使用pprof進(jìn)行監(jiān)控
一下兩種使用pprof進(jìn)行性能監(jiān)控的方式只能生成監(jiān)控信息文件,具體的分析需要使用go tool pprof [binary] file
進(jìn)行查看和分析揪荣。
3.1 非Web應(yīng)用程序
非Web應(yīng)用程序使用包runtime/pprof
庐镐,生成監(jiān)控文件。
下面示例進(jìn)行CPU監(jiān)控变逃,并將監(jiān)控?cái)?shù)據(jù)存放在當(dāng)前項(xiàng)目的pprof/profile_file/profile_file文件中。
import (
"log"
"os"
"path/filepath"
"runtime/pprof"
)
// 進(jìn)行CPU監(jiān)控
func CreateProfileFile() {
dir, err := os.Getwd()
if err != nil {
log.Fatalln("get current directory failed.", err)
}
fileName := filepath.Join(dir, "pprof", "profile_file", "profile_file")
f, _ := os.Create(fileName)
// start to record CPU profile and write to file `f`
_ = pprof.StartCPUProfile(f)
// stop to record CPU profile
defer pprof.StopCPUProfile()
// TODO do something
}
3.2 Web應(yīng)用程序
Web應(yīng)用程序使用包net/http/pprof
怠堪,可以搭建Web服務(wù)器查看監(jiān)控信息揽乱。通過http://locahost:6060/debug/pprof進(jìn)行查看相關(guān)的監(jiān)控信息文件。
import (
"log"
"net/http"
_ "net/http/pprof"
"os"
"runtime"
)
func main() {
log.SetFlags(log.Lshortfile | log.LstdFlags)
log.SetOutput(os.Stdout)
runtime.GOMAXPROCS(1)
runtime.SetMutexProfileFraction(1)
runtime.SetBlockProfileRate(1)
go func() {
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
注意
如果你使用自定義的 Mux粟矿,則需要手動注冊一些路由規(guī)則:
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
4 pprof監(jiān)控信息使用
golang原生自帶pprof工具的go tool pprof [binary] file
命令進(jìn)入交互式終端來排查應(yīng)用程序的性能問題凰棉。其中,
-
binary
正在執(zhí)行的二進(jìn)制可執(zhí)行程序陌粹,可選撒犀。 -
file
pprof監(jiān)控生成的文件√椭龋可以是具體的文件如profile.pprof或舞,也可以是web站點(diǎn)的地址,如http://localhost:6060/debug/pprof/profile蒙幻。
進(jìn)入終端之后映凳,排查性能問題的三個命令為: -
top
查看資源較高的調(diào)用。 -
list
list 代碼片段
查看問題代碼具體位置邮破。 -
web
在Web Browser上圖形化顯示當(dāng)前的資源監(jiān)控內(nèi)容诈豌。需要事先安裝graphviz。
web
命令的實(shí)際行為是產(chǎn)生一個.svg
文件抒和,并調(diào)用系統(tǒng)里設(shè)置的默認(rèn)打開.svg
的程序打開它矫渔。如果系統(tǒng)里打開.svg
的默認(rèn)程序并不是瀏覽器(比如代碼編輯器),需要設(shè)置一下默認(rèn)使用瀏覽器打開.svg
文件摧莽。然后瀏覽器自動打開庙洼,可以看到:
如果需要其他命令,可以在pprof交互式終端里輸入help
查看其他命令的使用方法。例如送膳,
-
svg
生成svg圖员魏。 -
pdf
生成pdf文件,顯示svg圖叠聋。 -
png
生成png圖片撕阎,顯示svg圖。 - ...
當(dāng)然還有很多其他的命令和選項(xiàng)碌补,請自行學(xué)習(xí)驗(yàn)證虏束。
5 pprof監(jiān)控信息展示——火焰圖
火焰圖(Flame Graph)是 Bredan Gregg 創(chuàng)建的一種性能分析圖表,因?yàn)樗臉幼咏苹鹧娑妹谜隆olang性能監(jiān)控結(jié)果可以轉(zhuǎn)換成火焰圖來進(jìn)行直觀展示镇匀。火焰圖 svg 文件可以通過瀏覽器打開袜啃,它展示調(diào)用圖的最大優(yōu)點(diǎn)是火焰圖動態(tài)的——可以通過點(diǎn)擊每個方塊來分析它上層概況/下層詳細(xì)的內(nèi)容汗侵。
火焰圖的調(diào)用順序從下到上,每個方塊代表一個函數(shù)群发,它上面一層表示這個函數(shù)會調(diào)用哪些函數(shù)晰韵,方塊的大小代表了占用資源值的多少(例如,CPU使用時間的長短熟妓,內(nèi)存使用的大小等)雪猪。火焰圖的配色并沒有特殊的意義起愈,默認(rèn)的紅只恨、黃配色是為了更像火焰而已。
生成火焰圖抬虽,有兩種方式:go-torch(golang version < 1.10)和golang原生的pprof(golang version < 1.10+的pprof集成了火焰圖功能)官觅。
5.1 go-torch
go-torch是uber 開源的一個工具。go-torch可以直接讀取 golang 的監(jiān)控?cái)?shù)據(jù)文件斥赋,并生成一個火焰圖的 svg 文件缰猴。
go-torch工具使用非常簡單,最簡單的是使用go-torch的docker鏡像運(yùn)行疤剑,無需安裝go-torch滑绒。
- 首先進(jìn)行docker安裝(ubuntu)。其他操作系統(tǒng)的安裝參考codker安裝隘膘。
- 運(yùn)行g(shù)o-rorch鏡像
uber/go-torch
疑故。
如果不知道相關(guān)命令,可以執(zhí)行$ sudo docker run uber/go-torch -h
查看go-torch的使用幫助弯菊。
$ sudo docker run uber/go-torch -h
Usage:
go-torch [options] [binary] <profile source>
pprof Options:
-u, --url= Base URL of your Go program (default:
http://localhost:8080)
--suffix= URL path of pprof profile (default: /debug/pprof/profile)
-b, --binaryinput= File path of previously saved binary profile. (binary
profile is anything accepted by
https://golang.org/cmd/pprof)
--binaryname= File path of the binary that the binaryinput is for, used
for pprof inputs
-t, --seconds= Number of seconds to profile for (default: 30)
--pprofArgs= Extra arguments for pprof
Output Options:
-f, --file= Output file name (must be .svg) (default: torch.svg)
-p, --print Print the generated svg to stdout instead of writing to
file
-r, --raw Print the raw call graph output to stdout instead of
creating a flame graph; use with Brendan Gregg's flame
graph perl script (see
https://github.com/brendangregg/FlameGraph)
--title= Graph title to display in the output file (default: Flame
Graph)
--width= Generated graph width (default: 1200)
--hash Colors are keyed by function name hash
--colors= set color palette. choices are: hot (default), mem, io,
wakeup, chain, java, js, perl, red, green, blue, aqua,
yellow, purple, orange
--cp Use consistent palette (palette.map)
--reverse Generate stack-reversed flame graph
--inverted icicle graph
Help Options:
-h, --help Show this help message
最重要的命令有五個:
可選參數(shù)選項(xiàng) | 描述 | 默認(rèn)值 | 備注 |
---|---|---|---|
-u, --url= | golang代碼的基礎(chǔ)URL——[scheme]://[host]:[port] | http://localhost:8080 | |
--suffix= | pprof profile文件URL路徑 | /debug/pprof/profile | |
-t, --seconds= | 執(zhí)行profile的時間長度纵势,單位是秒 | 30 | |
-f, --file= | 輸出文件的名稱 | torch.svg | 文件擴(kuò)展名必須是 .svg |
-p, --print | 將生成的svg文件打印到標(biāo)準(zhǔn)輸出,而不是寫入文件 |
所有參數(shù)都是可選參數(shù)。如果沒有任何參數(shù)钦铁,默認(rèn)情況下软舌,會嘗試從http://localhost:8080/debug/pprof/profile 獲取監(jiān)控?cái)?shù)據(jù)。
例如牛曹,從服務(wù)器http://10.0.2.15:6060/debug/pprof/block獲取阻塞信息佛点,并將生成的svg文件打印到標(biāo)準(zhǔn)輸出中,然后信息重定向保存到本地torch.svg文件黎比。
$ sudo docker run uber/go-torch -u http://10.0.2.15:6060 --suffix=/debug/pprof/block -p > torch.svg
INFO[02:33:36] Run pprof command: go tool pprof -raw -seconds 30 http://10.0.2.15:6060/debug/pprof/block
INFO[02:33:36] Printing svg to stdout
第一次執(zhí)行由于需要安裝go-torch相關(guān)依賴和鏡像超营,等待時間較長。
執(zhí)行成功之后阅虫,本地會生成一個torch.svg文件演闭。右鍵通過瀏覽器打開,可以看到火焰圖颓帝,如下圖所示:
使用go-torch的docker鏡像可以在windows操作系統(tǒng)使用米碰。
注:當(dāng)然了,可以將go-torch和FlameGraph工具分別安裝购城,然后執(zhí)行go-torch
命令见间。具體參數(shù)和go-torch鏡像執(zhí)行-h
顯示的參數(shù)相同。此處不再贅述工猜。
5.2 使用golang的pprof查看火焰圖
使用go tool pprof可以在Web界面上查看所有類型的資源監(jiān)控圖。
例如菱蔬,使用pprof查看Web服務(wù)器的阻塞監(jiān)控?cái)?shù)據(jù)篷帅,并將結(jié)果展示在6061端口。通過http://localhost:6062/ui/flamegraph即可查看生成的火焰圖拴泌。
$ go tool pprof -http=:6061 http://localhost:6060/debug/pprof/block
Fetching profile over HTTP from http://localhost:6060/debug/pprof/block
Saved profile in /home/jerry/pprof/pprof.___go_build_main_go.contentions.delay.005.pb.gz
從執(zhí)行命令的過程魏身,可以看到pprof工具從http://localhost:6060/debug/pprof/block獲取監(jiān)控?cái)?shù)據(jù),并保存到本地:/home/jerry/pprof/pprof.___go_build_main_go.contentions.delay.005.pb.gz蚪腐。然后對該文件進(jìn)行分析箭昵,并啟動一個Web服務(wù)器:http://localhost:6061。一般會自動彈出一個瀏覽器并顯示結(jié)果——默認(rèn)顯示的是graph回季。但是可以從第一行的菜單中切換View家制,選擇Flame Graph即可顯示火焰圖。
參考
1 golang pprof 實(shí)戰(zhàn)
2 Go pprof和火焰圖
3 使用 pprof 和火焰圖調(diào)試 golang 應(yīng)用
4 go pprof詳細(xì)理解及使用
5 使用pprof及Go 程序的性能優(yōu)化