go 性能監控神器--pprof

pprof簡介

pprof是go自身提供的工具鏈,可以用來做性能監控。pprof有兩個包:

  • runtime/pprof
    pprof的具體實現,所有類型的代碼都可以使用。如果不是Web應用程序,建議使用該包。
  • net/http/pprof
    對runtime/pprof包進行簡單封裝,并在http端口上暴露出來。適合Web應用程序使用。

pprof監控內容

pprof監控的內容項目入下表所示。

類型 描述 備注
allocs 內存分配情況的采樣信息 可以用瀏覽器打開,但可讀性不高
blocks 阻塞操作情況的采樣信息 可以用瀏覽器打開,但可讀性不高
cmdline 顯示程序啟動命令及參數 可以用瀏覽器打開,但可讀性不高
goroutine 當前所有協程的堆棧信息 可以用瀏覽器打開,但可讀性不高
heap 堆上內存使用情況的采樣信息 可以用瀏覽器打開,但可讀性不高
mutex 鎖爭用情況的采樣信息 可以用瀏覽器打開,但可讀性不高
profile CPU 占用情況的采樣信息 瀏覽器打開會下載文件
threadcreate 系統線程創建情況的采樣信息 可以用瀏覽器打開,但可讀性不高
trace 程序運行跟蹤信息 瀏覽器打開會下載文件

使用pprof進行監控

一下兩種使用pprof進行性能監控的方式只能生成監控信息文件,具體的分析需要使用go tool pprof [binary] file進行查看和分析。

非Web應用程序

非Web應用程序使用包runtime/pprof,生成監控文件。
下面示例進行CPU監控,并將監控數據存放在當前項目的pprof/profile_file/profile_file文件中。

import (
  "log"
  "os"
  "path/filepath"
  "runtime/pprof"
)
// 進行CPU監控
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
}

Web應用程序

Web應用程序使用包net/http/pprof,可以搭建Web服務器查看監控信息。通過http://locahost:6060/debug/pprof進行查看相關的監控信息文件。

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,則需要手動注冊一些路由規則:

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)

pprof監控信息使用

golang原生自帶pprof工具的go tool pprof [binary] file命令進入交互式終端來排查應用程序的性能問題。其中,

  • binary
    正在執行的二進制可執行程序,可選。

  • file
    pprof監控生成的文件。可以是具體的文件如profile.pprof,也可以是web站點的地址,如http://localhost:6060/debug/pprof/profile
    進入終端之后,排查性能問題的三個命令為:

  • top
    查看資源較高的調用。

  • list
    list 代碼片段查看問題代碼具體位置。

  • web
    在Web Browser上圖形化顯示當前的資源監控內容。需要事先安裝graphviz。
    web命令的實際行為是產生一個 .svg文件,并調用系統里設置的默認打開 .svg 的程序打開它。如果系統里打開 .svg 的默認程序并不是瀏覽器(比如代碼編輯器),需要設置一下默認使用瀏覽器打開 .svg 文件。然后瀏覽器自動打開,可以看到:


    示例block的監控信息

如果需要其他命令,可以在pprof交互式終端里輸入help查看其他命令的使用方法。例如,

  • svg
    生成svg圖。

  • pdf
    生成pdf文件,顯示svg圖。

  • png
    生成png圖片,顯示svg圖。

  • ...
    當然還有很多其他的命令和選項,請自行學習驗證。

pprof監控信息展示——火焰圖

火焰圖(Flame Graph)是 Bredan Gregg 創建的一種性能分析圖表,因為它的樣子近似火焰而得名。golang性能監控結果可以轉換成火焰圖來進行直觀展示。火焰圖 svg 文件可以通過瀏覽器打開,它展示調用圖的最大優點是火焰圖動態的——可以通過點擊每個方塊來分析它上層概況/下層詳細的內容。

火焰圖的調用順序從下到上,每個方塊代表一個函數,它上面一層表示這個函數會調用哪些函數,方塊的大小代表了占用資源值的多少(例如,CPU使用時間的長短,內存使用的大小等)。火焰圖的配色并沒有特殊的意義,默認的紅、黃配色是為了更像火焰而已。

生成火焰圖,有兩種方式:go-torch(golang version < 1.10)和golang原生的pprof(golang version < 1.10+的pprof集成了火焰圖功能)。

go-torch

go-torch是uber 開源的一個工具。go-torch可以直接讀取 golang 的監控數據文件,并生成一個火焰圖的 svg 文件。

go-torch工具使用非常簡單,最簡單的是使用go-torch的docker鏡像運行,無需安裝go-torch。

  1. 首先進行docker安裝(ubuntu)。其他操作系統的安裝參考codker安裝。
  2. 運行go-rorch鏡像 uber/go-torch 。
    如果不知道相關命令,可以執行$ 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

最重要的命令有五個:

可選參數選項 描述 默認值 備注
-u, --url= golang代碼的基礎URL——[scheme]://[host]:[port] http://localhost:8080
--suffix= pprof profile文件URL路徑 /debug/pprof/profile
-t, --seconds= 執行profile的時間長度,單位是秒 30
-f, --file= 輸出文件的名稱 torch.svg 文件擴展名必須是 .svg
-p, --print 將生成的svg文件打印到標準輸出,而不是寫入文件

所有參數都是可選參數。如果沒有任何參數,默認情況下,會嘗試從http://localhost:8080/debug/pprof/profile 獲取監控數據。

例如,從服務器http://10.0.2.15:6060/debug/pprof/block獲取阻塞信息,并將生成的svg文件打印到標準輸出中,然后信息重定向保存到本地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

第一次執行由于需要安裝go-torch相關依賴和鏡像,等待時間較長。

執行成功之后,本地會生成一個torch.svg文件。右鍵通過瀏覽器打開,可以看到火焰圖,如下圖所示:


go-torch生成火焰圖示例

使用go-torch的docker鏡像可以在windows操作系統使用。

注:當然了,可以將go-torch和FlameGraph工具分別安裝,然后執行go-torch命令。具體參數和go-torch鏡像執行-h顯示的參數相同。此處不再贅述。

使用golang的pprof查看火焰圖

使用go tool pprof可以在Web界面上查看所有類型的資源監控圖。
例如,使用pprof查看Web服務器的阻塞監控數據,并將結果展示在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

從執行命令的過程,可以看到pprof工具從http://localhost:6060/debug/pprof/block獲取監控數據,并保存到本地:/home/jerry/pprof/pprof.___go_build_main_go.contentions.delay.005.pb.gz。

然后對該文件進行分析,并啟動一個Web服務器:http://localhost:6061。一般會自動彈出一個瀏覽器并顯示結果——默認顯示的是graph。但是可以從第一行的菜單中切換View,選擇Flame Graph即可顯示火焰圖。

pprof啟動的性能分析圖形化默認Web頁面

pprof啟動的性能分析圖形化火焰圖

轉載自 https://mp.weixin.qq.com/s/b8kmip1lcuaCumEWr8kJKw

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,224評論 6 529
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,916評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,014評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,466評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,245評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,795評論 1 320
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,869評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,010評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,524評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,487評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,634評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,173評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,884評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,282評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,541評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,236評論 3 388
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,623評論 2 370

推薦閱讀更多精彩內容