這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Golang為我們提供了非常方便的效能測試工具pprof,使用pprof可以非常方便地對Go程式的運行效率進行監測。本文講述如何使用pprof對Go程式進行效能測試,並使用qcachegrind查看效能測試的輸出檔案。
載入pprof模組
想要對一個Go程式進行pprof監測,第一步是在main函數所在的模組中添加 net/http/pprof 模組。import後面的“_”是一定要加上的。
import _ "net/http/pprof"
運行HTTP伺服器
如果你的程式不是一個Web伺服器,那麼你還需要再程式中啟動一個Http伺服器,如下所示:
go func() { http.ListenAndServe("localhost:13001", nil)}()
重新編譯並運行程式。然後我們可以通過網頁瀏覽器查看當前程式的運行狀態:http://localhost:13001/debug/pprof 。如果運行正常,可以看到類似如下的輸出:
/debug/pprof/profiles:0block9goroutine7heap0mutex12threadcreatefull goroutine stack dump
在這個網頁裡我們可以查看程式當前的goroutine運行狀態、記憶體使用量情況等資訊。
使用go tool pprof命令
開啟命令列,輸入命令: go tool pprof http://localhost:13001/debug/pprof/profile ,此時命令列會卡出,並列印類似如下資訊:
C:\Users\Administrator>go tool pprof http://localhost:13001/debug/pprof/profileFetching profile from http://localhost:13001/debug/pprof/profilePlease wait... (30s)
Saved profile in \pprof\pprof.localhost:13001.samples.cpu.007.pb.gz
Entering interactive mode (type "help" for commands)
在經過30秒的等待之後,效能測試完成,會在本地儲存壓測結果。
可以使用top命令查看開銷最大的一些函數,或者使用web命令直接在網頁中查看,其他的命令還包括:svg,pdf,png等,你可以選擇自己所習慣的工具查看效能檢測結果。
(pprof) top20970ms of 1130ms total (85.84%)Showing top 20 nodes out of 86 (cum >= 20ms) flat flat% sum% cum cum% 280ms 24.78% 24.78% 300ms 26.55% runtime.stdcall1 100ms 8.85% 33.63% 110ms 9.73% runtime.acquirep 100ms 8.85% 42.48% 100ms 8.85% runtime.siftdownTimer 90ms 7.96% 50.44% 90ms 7.96% runtime.osyield 80ms 7.08% 57.52% 260ms 23.01% runtime.timerproc 60ms 5.31% 62.83% 60ms 5.31% runtime.memeqbody 50ms 4.42% 67.26% 50ms 4.42% runtime.casgstatus 30ms 2.65% 69.91% 30ms 2.65% runtime.cgocall 30ms 2.65% 72.57% 430ms 38.05% runtime.exitsyscallfast_pidle 20ms 1.77% 74.34% 20ms 1.77% runtime.asmstdcall 20ms 1.77% 76.11% 20ms 1.77% runtime.goready 20ms 1.77% 77.88% 20ms 1.77% runtime.pidleget 20ms 1.77% 79.65% 60ms 5.31% runtime.startm 10ms 0.88% 80.53% 20ms 1.77% github.com/xiaonanln/goworld/netutil.(*PacketConnection).Flush 10ms 0.88% 81.42% 10ms 0.88% github.com/xiaonanln/goworld/netutil.allocPacket 10ms 0.88% 82.30% 80ms 7.08% main.(*DispatcherService).getEntityDispatcherInfoForRead 10ms 0.88% 83.19% 10ms 0.88% net.(*fdMutex).rwunlock 10ms 0.88% 84.07% 10ms 0.88% runtime.(*guintptr).cas 10ms 0.88% 84.96% 10ms 0.88% runtime.acquirep1 10ms 0.88% 85.84% 20ms 1.77% runtime.asmcgocall
值得一提的是,如果我們的程式中一台Linux伺服器上運行,我們也可以在自己的Windows電腦上運行go tool pprof命令,只需要將網址裡的localhost替換為Linux伺服器的地址即可。
使用qcachegrind查看效能監測結果
相比top、web、svg等命令,查看效能檢測結果最方便的工具還是qcachegrind。首先需要前往 https://sourceforge.net/projects/qcachegrindwin/files/ 下載Windows版的qcachegrind。
在go tool pprof的命令列裡,使用callgrind命令產生qcachegrind工具所支援的檔案類型:
(pprof) callgrindGenerating report in profile010.callgraph.out
然後使用下載的qcachegrind.exe開啟產生的檔案即可,此處為:profile010.callgraph.out。使用qcachegrind可以在各個函數之間自由跳轉,查看函數內部的CPU佔用情況,相對其他格式要更加靈活方便。例如以下是我們對GoWorld遊戲伺服器進行一次效能測試的結果。
不成熟的最佳化是萬惡之源!因此我們在對自己的Go程式進行最佳化之前,不妨先使用go tool pprof對程式效能進行檢測,然後對關鍵的效能瓶頸部分進行最佳化,這樣才會起到事半功倍的效果。Golang提供的pprof是進行效能測試的利器,經過我們的實際使用發現,即使在開啟效能測試的30s裡,pprof對程式帶來的效能損耗並不大。
對Go語言服務端開發感興趣的朋友歡迎加入QQ討論群:662182346