線上問題排查之golang使用json進行對象copy
前言:
記一次golang使用json進行對象copy的內存溢出問題排查
問題現象:新增的功能,灰度部署在k8s集群的服務,發(fā)現機器老是被打崩,因為是灰度,且控制了qps在100多,但是機器卻崩潰。通過對灰度機器的監(jiān)控。發(fā)現是內存太高導致機器掛掉。此次回顧一下排查歷程。
增加GC次數,從而可以通過pprof去抓取內存使用情況:
將程序的GOGC由原先的2000改為200,從而增加GC次數,然后去抓取內存消耗情況
- 第一步操作完成,經驗證機器可以正常運行,借助gops導出cpu運行圖和內存消耗情況
- ①將編譯好的linux版本的gops導入到目標機器上
- ②執(zhí)行命令 gops 查看正在運行的程序的pid

- ③執(zhí)行命令獲取cpu運行狀態(tài) gops pprof-cpu 27
- ④執(zhí)行命令獲取內存消耗情況 gops pprof-heap 27
執(zhí)行上述兩個命令后,其會生成文件在tmp目錄下 :


//⑤將生成的文檔下載到本地后,分別執(zhí)行 go tool pprof -http=:8080 cpu_profile* go tool pprof -http=:8081 heap_profile* //在本地生成可視化
內存的火焰圖如下 :

cpu的火焰圖如下:

通過對火焰圖的分析,可以明顯的看到json.Marshal 和 json.Unmarshal 有明顯的占用問題。跟著火焰圖去找尋調用此處的該方法,定位到

此處就不列出runtime.Context對象的具體情況了,你可以理解為里面多處指針,多處切片。反正就是結構體很大 【PS:改天針對大結構體出個壓測結果】
發(fā)現問題后更換如下代碼進行對象copy,注意此拷貝結構體不能有小寫字母開頭。另外建議盡量少進行對象copy,盡可能的細化到需要copy的地方
/**
* @Description:深拷貝數據 (慎用--結構體不能有小寫字母開頭)
*/
func DeepCopy(dst, src interface{}) error {
var buf bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(src); err != nil {
return err
}
return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
}到此這篇關于線上問題排查之golang使用json進行對象copy的文章就介紹到這了,更多相關 golang copy內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go在GoLand中引用github.com中的第三方包具體步驟
這篇文章主要給大家介紹了關于Go在GoLand中引用github.com中第三方包的具體步驟,文中通過圖文介紹的非常詳細,對大家學習或者使用Go具有一定的參考價值,需要的朋友可以參考下2024-01-01

