go中提供了pprof包來做代碼的性能監控,在兩個地方有包:
- net/http/pprof
- runtime/pprof
其實net/http/pprof中只是使用runtime/pprof包來進行封裝了一下,並在http端口上暴露出來。
使用 net/http/pprof 做WEB服務器的性能監控
如果你的go程序是用http包啟動的web服務器,想要查看自己的web服務器的狀態。這個時候就可以選擇net/http/pprof。
import _ "net/http/pprof"
然后就可以在瀏覽器中使用http://localhost:port/debug/pprof/ 直接看到當前web服務的狀態,包括CPU占用情況和內存使用情況等。
當然,非WEB的也可以用下面方式啟動WEB。
在 main 方法中增加
func main() {
go func() {
http.ListenAndServe("localhost:6060", nil)
}()
下圖就是訪問該網址的一次截圖:
CPU消耗分析
使用 runtime/pprof 做應用程序性能監控
關鍵代碼:
import "runtime/pprof"
func main() {
f, err := os.OpenFile("./tmp/cpu.prof", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
defer f.Close()
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
注意,有時候 defer f.Close(), defer pprof.StopCPUProfile() 會執行不到,這時候我們就會看到 prof 文件是空的, 我們需要在自己代碼退出的地方,增加上下面兩行,確保寫文件內容了。
pprof.StopCPUProfile()
f.Close()
對產生的文件進行分析:
我們可以使用 go tool pprof (應用程序) (應用程序的prof文件) 方式來對這個 prof 文件進行分析。
$ go tool pprof HuaRongDao ./tmp/cpu.prof
Entering interactive mode (type "help" for commands)
(pprof)
一些常用 pprof 的命令:
top
在默認情況下,top命令會輸出以本地取樣計數為順序的列表。我們可以把這個列表叫做本地取樣計數排名列表。
(pprof) top
2700ms of 3200ms total (84.38%)
Dropped 58 nodes (cum <= 16ms)
Showing top 10 nodes out of 111 (cum >= 80ms)
flat flat% sum% cum cum%
670ms 20.94% 20.94% 670ms 20.94% runtime.mach_semaphore_signal
580ms 18.12% 39.06% 590ms 18.44% runtime.cgocall
370ms 11.56% 50.62% 370ms 11.56% runtime.mach_semaphore_wait
360ms 11.25% 61.88% 360ms 11.25% runtime.memmove
210ms 6.56% 68.44% 580ms 18.12% golang.org/x/mobile/gl.(*context).DoWork
120ms 3.75% 72.19% 120ms 3.75% runtime.usleep
110ms 3.44% 75.62% 110ms 3.44% image/png.filterPaeth
100ms 3.12% 78.75% 160ms 5.00% compress/flate.(*decompressor).huffSym
100ms 3.12% 81.88% 100ms 3.12% image/draw.drawNRGBASrc
80ms 2.50% 84.38% 80ms 2.50% runtime.memclr
(pprof)
參考: https://github.com/hyper-carrot/go_command_tutorial/blob/master/0.12.md
默認情況下top命令會列出前10項內容。但是如果在top命令后面緊跟一個數字,那么其列出的項數就會與這個數字相同。
web
與gv命令類似,web命令也會用圖形化的方式來顯示概要文件。但不同的是,web命令是在一個Web瀏覽器中顯示它。如果你的Web瀏覽器已經啟動,那么它的顯示速度會非常快。如果想改變所使用的Web瀏覽器,可以在Linux下設置符號鏈接/etc/alternatives/gnome-www-browser或/etc/alternatives/x-www-browser,或在OS X下改變SVG文件的關聯Finder。
mac 下 修改默認打開方式: 右鍵一個想處理的文件,按alt 鍵(lion)出現always open with,然后打開,整個過程中, 先右鍵,然后一直按 alt, 一直到打開為止。
參考資料:
go tool pprof
https://github.com/hyper-carrot/go_command_tutorial/blob/master/0.12.md
Go的pprof使用
http://www.cnblogs.com/yjf512/archive/2012/12/27/2835331.html
Profiling Go Programs
https://blog.golang.org/profiling-go-programs
內存泄漏或消耗分析
關鍵代碼
fm, err := os.OpenFile("./tmp/mem.out", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
log.Fatal(err)
}
pprof.WriteHeapProfile(fm)
fm.Close()
在我們需要生成當時的內存情況時,只需要執行上面代碼即可。
觸發的條件可以通過 http 的一個接口,或者退出時,或者接收到某個特殊信號,這些邏輯就需要自己實現了。
分析方法,跟之上CPU的分析方法一致。
參考資料:
[golang]內存不斷增長bytes.makeSlice
http://studygolang.com/articles/2763