Tag: cpu

1 Posts

thumbnail
golang cpu性能统计解读
依赖前提 程序中引入pprof包后可以直接查看线上的服务性能数据 import ( _ "net/http/pprof" ) 触发方法 # 比如程序对外暴露8001端口 go tool pprof http://127.0.0.1:8001/debug/pprof/profile?seconds=60 结果解读 如果没有添加统计时间参数,则触发之后会默认进入30s统计阶段,之后进入交互是界面,可以查看性能数据。我们先这样看,top -cum,是按照cum列按占用时间顺序显示前10个。 [@zyz-4 ~]$ go tool pprof http://localhost:8001/debug/pprof/profile Fetching profile from http://localhost:8001/debug/pprof/profile Please wait... (30s) Saved profile in /data/home/jiyalei/pprof/pprof.localhost:8001.samples.cpu.002.pb.gz Entering interactive mode (type "help" for commands) (pprof) top -cum 10ms of 80ms total (12.50%) Showing top 10 nodes out of 55 (cum >= 10ms) flat flat% sum% cum cum% 0 0% 0% 60ms 75.00% runtime.goexit 0 0% 0% 30ms 37.50% dproxy/helper.(*DataManager).StartRun 0 0% 0% 30ms 37.50% dproxy/helper.(*DataManager).realRun 10ms 12.50% 12.50% 30ms 37.50% dproxy/helper.(*DataManager).startRealTimer 0 0% 12.50% 20ms 25.00% dproxy/helper.(*RpcClient).RealGetFunc 0 0% 12.50% 10ms 12.50% dproxy/helper.(*RpcClient).GetNewClient 0 0% 12.50% 10ms 12.50% encoding/gob.(*Encoder).Encode 0 0% 12.50% 10ms 12.50% encoding/gob.(*Encoder).EncodeValue 0 0% 12.50% 10ms 12.50% encoding/gob.(*Encoder).encode 0 0% 12.50% 10ms 12.50% encoding/gob.(*Encoder).encodeStruct (pprof) top命令默认显示10个,可以通过topN的方式显示N个,cum参数表示按照cum列排序。 flat的意思是本地取样计数,cum的意思是累积取样计数,具体含义引用自官方文档: 本地取样计数和累积取样计数。本地取样计数的含义是当前函数在取样中直接出现的次数。累积取样计数的含义是当前函数以及当前函数直接或间接调用的函数在取样中直接出现的次数。所以,存在这样一种场景:对于一个函数来说,它的本地取样计数是0。因为它没有在取样中直接出现过。但是,由于它直接或间接调用的函数频繁的直接出现在取样中,所以这个函数的累积取样计数却会很高。我们以上图中的函数mian.main为例。由于main.main函数在所有取样中都没有直接出现过,所以它的本地取样计数为0。但又由于它是命令源码文件中的入口函数,程序中其他的函数都直接或间接的被它调用。所以,它的累积取样计数是所有函数中最高的。注意,不论是本地取样计数还是累积取样计数都没有把函数对自身的调用计算在内。函数对自身的调用又被称为递归调用. 我们通常看累计取样计数cum的时间,可以大致体现出来当前的耗时。可以通过list + 函数名的方式查看具体函数内部的占用时间,仅限于“触发方法二”: (pprof) list StartRun Total: 70ms ROUTINE ======================== dproxy/helper.(*DataManager).StartRun in /home/jiyalei/serving_clean/backend/src/dproxy/helper/dataManager.go 0 10ms (flat, cum) 14.29% of Total . . 72:} . . 73: . . 74://run DataManager on caller's gorountine, so caller will be blocked . . 75:func (self *DataManager) StartRun() { . .…