2020-03-19

1. 概述

在 go 語言中,主要關注的應用運行情況主要包括以下幾種:

  • CPU Profiling:CPU 分析劲弦,按照一定的頻率采集所監(jiān)聽的應用程序 CPU(含寄存器)的使用情況打掘,可確定應用程序在主動消耗 CPU 周期時花費時間的位置
  • Memory Profiling:內存分析,在應用程序進行堆分配時記錄堆棧跟蹤,用于監(jiān)視當前和歷史內存使用情況辰斋,以及檢查內存泄漏
  • Goroutine Profiling:報告 goroutines 的使用情況代芜,有哪些 goroutine埠褪,它們的調用關系是怎樣的
  • Block Profiling:阻塞分析,記錄 goroutine 阻塞等待同步(包括定時器通道)的位置,可以用來分析和查找死鎖等性能瓶頸
  • Mutex Profiling:互斥鎖分析蜒犯,報告互斥鎖的競爭情況

1.1 pprof

PProf是一個CPU分析器( cpu profiler)组橄, 它是gperftools工具的一個組件, 由Google工程師為分析多線程的程序所開發(fā)罚随,是用于可視化和分析性能分析數(shù)據(jù)的工具

pprof 以 profile.proto 讀取分析樣本的集合玉工,并生成報告以可視化并幫助分析數(shù)據(jù)(支持文本和圖形報告)

profile.proto 是一個 Protocol Buffer v3 的描述文件,它描述了一組 callstack 和 symbolization 信息淘菩, 作用是表示統(tǒng)計分析的一組采樣的調用棧遵班,是很常見的 stacktrace 配置文件格式

1.2 支持什么使用模式

  • Report generation:報告生成

  • Interactive terminal use:交互式終端使用

  • Web interface:Web 界面

2 安裝依賴工具:

1) 安裝 PProf

$ go get -u github.com/google/pprof

2) 安裝 FlameGraph

cd $WORK_PATH 
git clone https://github.com/brendangregg/FlameGraph.git
export PATH=$PATH:$WORK_PATH/FlameGraph

3)安裝 graphviz
pprof生成的prof文件時二進制的屠升,需要把這個二進制的文件轉換為我們人類可讀的,graphviz可以幫助我們把二進制的prof文件轉換為圖像

brew install graphviz 

3 采集狭郑、分析數(shù)據(jù)

做 Profiling 第一步就是怎么獲取應用程序的運行情況數(shù)據(jù)腹暖。go 語言提供了兩個庫:

  • runtime/pprof:采集程序(非 Server)的運行數(shù)據(jù)進行分析

  • net/http/pprof:對runtime/pprof包進行簡單封裝,并在http端口上暴露出來翰萨,采集 HTTP Server 的運行時數(shù)據(jù)進行分析

核心工具是:go tool pprof 命令:獲取和分析 Profiling 數(shù)據(jù)

更詳細的 pprof 使用方法可以參考 pprof --help 或者 pprof 文檔脏答。

對于不同類型的應該也有不同的采集和分析方式

3.1 工具型應用

3.1.1 腳本類

如果你的應用是一次性的,運行一段時間就結束亩鬼。那么最好的辦法殖告,就是在應用退出的時候把 profiling 的報告保存到文件中,進行分析雳锋。對于這種情況黄绩,可以使用 runtime/pprof

pprof 封裝了很好的接口供我們使用玷过,比如要想進行 CPU Profiling爽丹,可以調用 pprof.StartCPUProfile() 方法,它會對當前應用程序進行 CPU profiling辛蚊,并寫入到提供的參數(shù)中(w io.Writer)粤蝎,要停止調用 StopCPUProfile() 即可。

示例:

import (
    "os"
    "runtime/pprof"
)
func main() {
    f, _ := os.Create("cpu.prof")
    defer f.Close()

    do somethings...

    pprof.StopCPUProfile()
}

應用執(zhí)行結束后嚼隘,就會生成一個文件(cpu.prof)诽里,保存了我們的 CPU profiling 數(shù)據(jù)。

想要獲得內存的數(shù)據(jù)飞蛹,直接使用 WriteHeapProfile 就行谤狡,不用 startstop 這兩個步驟了:

f, err := os.Create(*memprofile)
pprof.WriteHeapProfile(f)f.Close()

3.1.2 通過測試用例進行性能測試

編寫測試用例

(1)新建 data/d_test.go,文件內容:

package data
 
import "testing"
 
const url = "https://github.com/EDDYCJY"
 
func TestAdd(t *testing.T) {
    s := Add(url)
    if s == "" {
        t.Errorf("Test.Add error!")
    }
}
 
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(url)
    }
}

(2)執(zhí)行測試用例卧檐,生成prof文件

$go test -bench=. -cpuprofile=cpu.prof

pkg: github.com/EDDYCJY/go-pprof-example/data

BenchmarkAdd-410000000187ns/op

PASS

ok      github.com/EDDYCJY/go-pprof-example/data2.300s

-memprofile 也可以了解一下

啟動 PProf 可視化界面

$go tool pprof -http=:8080 cpu.prof

3.2 服務型應用(web服務)

3.2.1 引入

如果你的應用是一直運行的墓懂,比如 web 應用,那么可以使用 net/http/pprof 庫霉囚,它能夠在提供 HTTP 服務進行分析捕仔。

import中只需要添加一行:

import _ "net/http/pprof"

main函數(shù)中啟動監(jiān)聽:

go func() {
    if err := http.ListenAndServe(fmt.Sprintf("%s:%s", "0.0.0.0", "6060"), nil); nil != err {
            panic(err)
        }
    }()

3.2.2 分析數(shù)據(jù)

3.2.2.1 通過 Web 界面

查看當前總覽:訪問 http://127.0.0.1:6060/debug/pprof/

/debug/pprof/
 
profiles:
0    block
5    goroutine
3    heap
0    mutex
9    threadcreate
 
full goroutine stack dump

這個頁面中有許多子頁面,咱們繼續(xù)深究下去盈罐,看看可以得到什么榜跌?

  • cpu(CPU Profiling): $HOST/debug/pprof/profile,默認進行 30s 的 CPU Profiling盅粪,得到一個分析用的 profile 文件

  • block(Block Profiling):$HOST/debug/pprof/block钓葫,查看導致阻塞同步的堆棧跟蹤

  • goroutine:$HOST/debug/pprof/goroutine,查看當前所有運行的 goroutines 堆棧跟蹤

  • heap(Memory Profiling): $HOST/debug/pprof/heap票顾,查看活動對象的內存分配情況

  • mutex(Mutex Profiling):$HOST/debug/pprof/mutex础浮,查看導致互斥鎖的競爭持有者的堆棧跟蹤

  • threadcreate:$HOST/debug/pprof/threadcreate帆调,查看創(chuàng)建新OS線程的堆棧跟蹤

pprof監(jiān)控的內容項目入下表所示。

3.2.2.1 通過交互式終端使用

能通過對應的庫獲取想要的 Profiling 數(shù)據(jù)之后(不管是文件還是 http)豆同,下一步就是要對這些數(shù)據(jù)進行保存和分析番刊,我們可以使用 go tool pprof 命令行工具。
(1)go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60

$ go tool pprof http://localhost:6060/debug/pprof/profile\?seconds\=60

Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=60

Saved profilein/Users/eddycjy/pprof/pprof.samples.cpu.007.pb.gz

Type: cpu

Duration: 1mins, Total samples = 26.55s (44.15%)

Entering interactive mode (type"help"forcommands,"o"foroptions)

(pprof)

執(zhí)行該命令后影锈,需等待 60 秒(可調整 seconds 的值)芹务,pprof 會進行 CPU Profiling。結束后將默認進入 pprof 的交互式命令模式精居,可以對分析的結果進行查看或導出锄禽。具體可執(zhí)行 pprof help 查看命令說明

(pprof) top10

Showing nodes accountingfor25.92s, 97.63% of 26.55s total

Dropped 85 nodes (cum <= 0.13s)

Showing top 10 nodes out of 21

      flat  flat%  sum%        cum  cum%

    23.28s 87.68% 87.68%    23.29s 87.72%  syscall.Syscall

    0.77s  2.90% 90.58%      0.77s  2.90%  runtime.memmove

    0.58s  2.18% 92.77%      0.58s  2.18%  runtime.freedefer

    0.53s  2.00% 94.76%      1.42s  5.35%  runtime.scanobject

    0.36s  1.36% 96.12%      0.39s  1.47%  runtime.heapBitsForObject

    0.35s  1.32% 97.44%      0.45s  1.69%  runtime.greyobject

    0.02s 0.075% 97.51%    24.96s 94.01%  main.main.func1

    0.01s 0.038% 97.55%    23.91s 90.06%  os.(*File).Write

    0.01s 0.038% 97.59%      0.19s  0.72%  runtime.mallocgc

    0.01s 0.038% 97.63%    23.30s 87.76%  syscall.Write
  • flat:給定函數(shù)上運行耗時

  • flat%:同上的 CPU 運行耗時總比例

  • sum%:給定函數(shù)累積使用 CPU 總比例

  • cum:當前函數(shù)加上它之上的調用運行總耗時

  • cum%:同上的 CPU 運行耗時總比例

最后一列為函數(shù)名稱潜必,在大多數(shù)的情況下靴姿,我們可以通過這五列得出一個應用程序的運行情況,加以優(yōu)化

pprof 不僅能打印出最耗時的地方(top)磁滚,還能列出函數(shù)代碼以及對應的取樣數(shù)據(jù)(list)佛吓、匯編代碼以及對應的取樣數(shù)據(jù)(disasm),而且能以各種樣式進行輸出垂攘,比如 svg维雇、gv、callgrind晒他、png吱型、gif等等

(2)go tool pprof http://localhost:6060/debug/pprof/heap

$ go tool pprof http://localhost:6060/debug/pprof/heap

Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap

Saved profilein/Users/eddycjy/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.008.pb.gz

Type: inuse_space

Entering interactive mode (type"help"forcommands,"o"foroptions)

(pprof) top

Showing nodes accountingfor837.48MB, 100% of 837.48MB total

     flat  flat%  sum%        cum  cum%

 837.48MB  100%  100%  837.48MB  100%  main.main.func1
  • -inuse_space:分析應用程序的常駐內存占用情況

  • -alloc_objects:分析應用程序的內存臨時分配情況

(3) go tool pprof http://localhost:6060/debug/pprof/block

(4) go tool pprof http://localhost:6060/debug/pprof/mutex

3.2.2.3 直接可視化查看(火焰圖)

只需添加一個參數(shù)-http并指定端口,即可直接在web頁面查看

go tool pprof -http=:8099 http://localhost:6060/debug/pprof/heap

或者通過pprof查看陨仅,效果是一樣的

$ pprof -http=:8099 http://localhost:6060/debug/pprof/heap
  1. 火焰圖
    它的最大優(yōu)點是動態(tài)的津滞。調用順序由上到下(A -> B -> C -> D),每一塊代表一個函數(shù)灼伤,越大代表占用 CPU 的時間更長触徐。同時它也支持點擊塊深入進行分析!
  1. Top
  1. Graph

框越大狐赡,線越粗代表它占用的時間越大哦

  1. Peek
  1. Source



    通過 PProf 的可視化界面撞鹉,我們能夠更方便、更直觀的看到 Go 應用程序的調用鏈颖侄、使用情況等鸟雏,并且在 View 菜單欄中,還支持如上多種方式的切換

你想想览祖,在煩惱不知道什么問題的時候孝鹊,能用這些輔助工具來檢測問題,是不是瞬間效率翻倍了呢 ?

總結

在本章節(jié)穴墅,粗略地介紹了 Go 的性能利器 PProf惶室。在特定的場景中温自,PProf 給定位、剖析問題帶了極大的幫助

參考鏈接:
https://blog.csdn.net/cscrazybing/article/details/78686941
http://www.brendangregg.com/flamegraphs.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末皇钞,一起剝皮案震驚了整個濱河市悼泌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夹界,老刑警劉巖馆里,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異可柿,居然都是意外死亡鸠踪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門复斥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來营密,“玉大人,你說我怎么就攤上這事目锭∑捞” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵痢虹,是天一觀的道長被去。 經常有香客問我,道長奖唯,這世上最難降的妖魔是什么惨缆? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮丰捷,結果婚禮上坯墨,老公的妹妹穿的比我還像新娘。我一直安慰自己瓢阴,他們只是感情好畅蹂,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著荣恐,像睡著了一般液斜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叠穆,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天少漆,我揣著相機與錄音,去河邊找鬼硼被。 笑死示损,一個胖子當著我的面吹牛,可吹牛的內容都是我干的嚷硫。 我是一名探鬼主播检访,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼始鱼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脆贵?” 一聲冷哼從身側響起医清,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卖氨,沒想到半個月后会烙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡筒捺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年柏腻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片系吭。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡五嫂,死狀恐怖,靈堂內的尸體忽然破棺而出村斟,到底是詐尸還是另有隱情贫导,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布蟆盹,位于F島的核電站,受9級特大地震影響闺金,放射性物質發(fā)生泄漏逾滥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一败匹、第九天 我趴在偏房一處隱蔽的房頂上張望寨昙。 院中可真熱鬧,春花似錦掀亩、人聲如沸舔哪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捉蚤。三九已至,卻和暖如春炼七,著一層夾襖步出監(jiān)牢的瞬間缆巧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工豌拙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留陕悬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓按傅,卻偏偏與公主長得像捉超,于是被迫代替她去往敵國和親胧卤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內容