
【譯文】原文地址
Golang是一個很神奇的語言。在開發(fā)系統(tǒng)應用或web應用時候,建議考慮采用Golang。Golang開發(fā)者的需求持續(xù)增長也是一個很好的證明。
通過分析利弊我嘗試了Go。我們有特定的使用場景,需要超低的構(gòu)建時間,同時盡可能少使用資源。并且,我們使用微服務架構(gòu),因此可能使用不同的技術(shù)棧而不是單一的一種。
總的來說,Golang+Graphql性能挺好的。每秒能處理大量的請求。正常請求和負載不會有問題。當我們使用壓測和性能測試腳本的時候問題出現(xiàn)了。

起初,我們發(fā)現(xiàn)應用異常是在大負載情況下。我們持續(xù)監(jiān)測資源,性能測試完一段時間后,我們的服務使用了集群的大量資源(CPU和內(nèi)存)。這使我們很沮喪和害怕因為沒有達到我們使用GO的初衷。因此,我們分析發(fā)現(xiàn)問題并不是Golang語言問題,而是我們代碼的bug。
下面聊聊pprof
來自pprof Github倉庫 Github repo.)的簡單介紹:
pprof是一個用于對收集的數(shù)據(jù)分析和可視化工具。pprof從profile.proto文件讀取收集的樣本數(shù)據(jù),并生成可視化的報告便于對數(shù)據(jù)進行分析??梢陨晌谋竞蛨D像報告。
pprof詳細文檔鏈接。只需使用很少代碼即可使用pprof。在生產(chǎn)環(huán)境中使用pprof也是安全的,它最大只需要5%的資源消耗。
使用pprof
使用pprof工具,生成了內(nèi)存和cpu的使用統(tǒng)計圖(下面PNG格式圖片)。一眼看去很明顯發(fā)現(xiàn)amqp_helper(隊列處理文件)存在問題。我分析了代碼,發(fā)現(xiàn)amqp連接沒有關(guān)閉,導致內(nèi)存占用。

圖中框越大說明占有資源越多。
如何解決
我推薦檢查pprof.go的init()函數(shù)。將有助于理解/debug/pprof路由。使用如下模版:
package main
import (
"net/http"
"net/http/pprof"
)
func main() {
// other code
// if your app is not serving on any port
// then create a simple webserver
go func() {
log.Println(http.ListenAndServe("localhost:8082", nil))
}()
}
當你訪問http://localhost:8082/debug,可以看到go提供各種資源使用統(tǒng)計。

生成圖表
保持前面程序運行,執(zhí)行如下命令生成圖表:
1、內(nèi)存統(tǒng)計
go tool pprof -png http://localhost:8082/debug/pprof/heap > heap.png
該命令會在當前目錄生成heap.png文件。
2、CPU統(tǒng)計
go tool proof -png http://localhost:8082/debug/pprof/profile > profile.png
以下是一個CPU統(tǒng)計的圖表示例。使用上述命令,你可以創(chuàng)建和分析不同的統(tǒng)計數(shù)據(jù)。

常見內(nèi)存泄漏
1、沒有正確的關(guān)閉或未關(guān)閉連接。包括數(shù)據(jù)庫連接,隊列連接,第三方庫。
2、沒有正確使用defer()函數(shù)
3、使用大字符串/切片/子序列對其做多次操作。
4、指針音樂不使用的值
5、懸掛Goroutine
6、誤用Finalizer