go?pprof?的使用操作代碼
背景
最近合作開發(fā)一個項目,項目部署發(fā)現(xiàn)了才跑了沒多久,就直接宕機了,查看服務器信息發(fā)現(xiàn)在某個時間端內存猛的暴漲了非常多,由于是合作開發(fā)的項目,我仔細的檢查了自己的拿塊代碼,都沒啥問題,另一個開發(fā)也說自己的代碼沒啥問題。
這沒理沒據(jù)的爭論也不是個事,突然想起還有 pprof
這么個東西,正好能用上了。一頓操作下來,總算是找到了問題的根源。
pprof 是什么
pprof
是 go
中進行性能分析的工具,可以提供可視化數(shù)據(jù)查看。
pprof 的采樣方式
- runtime/pprof
- net/http/pprof
- test
這里舉例采樣內存信息。
package main import ( "os" "runtime/pprof" ) func main() { var buf = make([][1024 * 1024]byte, 0) for i := 0; i < 100; i++ { buf = append(buf, [1024 * 1024]byte{}) } f, err := os.OpenFile("heapProfile", os.O_CREATE|os.O_TRUNC|os.O_RDWR, os.ModePerm) if err != nil { return } err = pprof.WriteHeapProfile(f) if err != nil { return } println("結束") }
程序跑完之后會在本地生成 heapProfile
文件,命令行執(zhí)行 go tool pprof heapProfile
可進入終端交互,可以輸入 top
等命令查看:
這里可以輸入 web
查看可視化界面,如果遇到 Could not execute dot; may need to install graphviz.
錯誤,需要自行安裝,網上教程很多,本篇不提了。
順帶提一下 runtime.MemStats
結構體字段解釋
Alloc uint64 //golang語言框架堆空間分配的字節(jié)數(shù) TotalAlloc uint64 //從服務開始運行至今分配器為分配的堆空間總 和,只有增加,釋放的時候不減少 Sys uint64 //服務現(xiàn)在系統(tǒng)使用的內存 Lookups uint64 //被runtime監(jiān)視的指針數(shù) Mallocs uint64 //服務分配內存對象的次數(shù) Frees uint64 //服務回收內存對象的次數(shù) HeapAlloc uint64 //服務分配的堆內存字節(jié)數(shù) HeapSys uint64 //系統(tǒng)分配的作為運行棧的內存 HeapIdle uint64 //申請但是未分配的堆內存或者回收了的堆內存(空閑)字節(jié)數(shù) HeapInuse uint64 //正在使用的堆內存字節(jié)數(shù) HeapReleased uint64 //返回給OS的堆內存,類似C/C++中的free。 HeapObjects uint64 //堆內存塊申請的量 StackInuse uint64 //正在使用的棧字節(jié)數(shù) StackSys uint64 //系統(tǒng)分配的作為運行棧的內存 MSpanInuse uint64 //用于測試用的結構體使用的字節(jié)數(shù) MSpanSys uint64 //系統(tǒng)為測試用的結構體分配的字節(jié)數(shù) MCacheInuse uint64 //mcache結構體申請的字節(jié)數(shù)(不會被視為垃圾回收) MCacheSys uint64 //操作系統(tǒng)申請的堆空間用于mcache的字節(jié)數(shù) BuckHashSys uint64 //用于剖析桶散列表的堆空間 GCSys uint64 //垃圾回收標記元信息使用的內存 OtherSys uint64 //golang系統(tǒng)架構占用的額外空間 NextGC uint64 //垃圾回收器檢視的內存大小 LastGC uint64 // 垃圾回收器最后一次執(zhí)行時間。 PauseTotalNs uint64 // 垃圾回收或者其他信息收集導致服務暫停的次數(shù)。 PauseNs [256]uint64 //一個循環(huán)隊列,記錄最近垃圾回收系統(tǒng)中斷的時間 PauseEnd [256]uint64 //一個循環(huán)隊列,記錄最近垃圾回收系統(tǒng)中斷的時間開始點。 NumForcedGC uint32 //服務調用runtime.GC()強制使用垃圾回收的次數(shù)。 GCCPUFraction float64 //垃圾回收占用服務CPU工作的時間總和。如果有100個goroutine,垃圾回收的時間為1S,那么就占用了100S。 BySize //內存分配器使用情況
net/http/pprof
需要引入 net/http/pprof
包
package main import ( "net/http" _ "net/http/pprof" ) func main() { _ = http.ListenAndServe("0.0.0.0:6060", nil) }
然后訪問服務地址 http://127.0.0.1:6060/debug/pprof
即可看到如下圖所示的調試界面:
- allocs:查看過去所有內存分配的樣本。
- block:查看導致阻塞同步的堆棧跟蹤。
- cmdline: 當前程序的命令行的完整調用路徑。
- goroutine:查看當前所有運行的 goroutines 堆棧跟蹤。
- heap:查看活動對象的內存分配情況。
- mutex:查看導致互斥鎖的競爭持有者的堆棧跟蹤。
- profile: 默認進行 30s 的 CPU Profiling,得到一個分析用的 profile 文件。
- threadcreate:查看創(chuàng)建新 OS 線程的堆棧跟蹤。
- trace:略,trace可以單獨寫一篇文章來介紹。
這里需要注意,如果需要對 block
和 mutex
的信息進行追蹤,需要在代碼中顯式加上以下代碼:
runtime.SetBlockProfileRate(1) // 開啟對阻塞操作的跟蹤,block runtime.SetMutexProfileFraction(1) // 開啟對鎖調用的跟蹤,mutex
gin 框架使用 pprof
gin
是 go
社區(qū)中使用較為廣泛的一個 http
服務框架,其使用 pprof
進行性能分析,也有現(xiàn)成的輪子可以使用,引入 github.com/gin-contrib/pprof
即可,其實就是對于 net/http/pprof
的一個包裝。
package main import ( "github.com/gin-contrib/pprof" "github.com/gin-gonic/gin" ) func main() { engine := gin.Default() pprof.Register(engine) }
test
-bench=. 進行性能測試,“.”是正則匹配,匹配了所有的測試函數(shù) -benchmem 打印出申請內存的次數(shù)。一般用于簡單的性能測試,不會導出數(shù)據(jù)文件。 -blockprofile block.out 將協(xié)程的阻塞數(shù)據(jù)寫入特定的文件(block.out)。如果-c,則寫成二進制文件。 -cpuprofile cpu.out 將協(xié)程的CPU使用數(shù)據(jù)寫入特定的文件(cpu.out)。如果-c,則寫成二進制文件。 -memprofile mem.out 將協(xié)程的內存申請數(shù)據(jù)寫入特定的文件(mem.out)。如果-c,則寫成二進制文件。 -mutexprofile mutex.out 將協(xié)程的互斥數(shù)據(jù)寫入特定的文件(mutex.out)。如果-c,則寫成二進制文件。 -trace trace.out 將執(zhí)行調用鏈寫入特定文件(trace.out)。
test
導出的數(shù)據(jù)也需要通過 go tool pprof
來分析。
火焰圖
安裝
go get -u github.com/google/pprof
啟動
pprof -http=:8080 heapProfile
訪問 http://localhost:8080
可以得到下圖:
每個塊都是可點擊的,可以進行深度分析。
總結
pprof
是 go
中做性能分析的很強大的一個工具,支持內存,cpu
,鎖,goroutine
等數(shù)據(jù)采集,本篇主要是做個簡單介紹,真正進行分析的時候,需要耐心了解各種圖,數(shù)據(jù)展示的含義,一般來說還是比較好理解的。
pprof
性能分析是個很大的知識點,本篇僅做了簡單的介紹,最好自己深入理解學習一下。
參考
golang pprof 實戰(zhàn)-CPU,heap,alloc,goroutine,mutex,block
到此這篇關于go pprof 的使用的文章就介紹到這了,更多相關go pprof 使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Golang小數(shù)操作指南之判斷小數(shù)點位數(shù)與四舍五入
這篇文章主要給大家介紹了關于Golang小數(shù)操作指南之判斷小數(shù)點位數(shù)與四舍五入的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-03-03