golang利用pprof与go-torch如何做性能分析

2020-01-28 13:11:54于海丽

安装go-torch

还有更方便的工具就是uber的go-torch了

安装很简单


go get github.com/uber/go-torch
cd $GOPATH/src/github.com/uber/go-torch
git clone https://github.com/brendangregg/FlameGraph.git

然后运行FlameGraph下的 拷贝flamegraph.pl 到 /usr/local/bin

火焰图分析CPU

使用命令


go-torch -u http://192.168.3.34:9909 --seconds 60 -f cpu.svg

会在当前目录下生成cpu.svg文件,使用浏览器打开

更直观的看到应用程序的问题。handlerData方法占用的cpu时间过长。然后就是去代码里分析并优化了。

火焰图分析内存

使用命令


go-torch http://192.168.3.34:9909/debug/pprof/heap --colors mem -f mem.svg

会在当前目录下生成cpu.svg文件,使用浏览器打开

使用runtime/pprof分析项目

如果你的项目不是web服务,比如是rpc服务等,就要使用runtime/pprof。他提供了很多方法,有时间可以看一下源码

我写了一个简单的工具类。用于调用分析


package profapp

import (
 "os"
 "rrnc_im/lib/zaplogger"
 "go.uber.org/zap"
 "runtime/pprof"
 "runtime"
)

func StartCpuProf() {
 f, err := os.Create("cpu.prof")
 if err != nil {
  zaplogger.Error("create cpu profile file error: ", zap.Error(err))
  return
 }
 if err := pprof.StartCPUProfile(f); err != nil {
  zaplogger.Error("can not start cpu profile, error: ", zap.Error(err))
  f.Close()
 }
}

func StopCpuProf() {
 pprof.StopCPUProfile()
}


//--------Mem
func ProfGc() {
 runtime.GC() // get up-to-date statistics
}

func SaveMemProf() {
 f, err := os.Create("mem.prof")
 if err != nil {
  zaplogger.Error("create mem profile file error: ", zap.Error(err))
  return
 }

 if err := pprof.WriteHeapProfile(f); err != nil {
  zaplogger.Error("could not write memory profile: ", zap.Error(err))
 }
 f.Close()
}

// goroutine block
func SaveBlockProfile() {
 f, err := os.Create("block.prof")
 if err != nil {
  zaplogger.Error("create mem profile file error: ", zap.Error(err))
  return
 }

 if err := pprof.Lookup("block").WriteTo(f, 0); err != nil {
  zaplogger.Error("could not write block profile: ", zap.Error(err))
 }
 f.Close()
}

在需要分析的方法内调用这些方法就可以 比如我是用rpc开放了几个方法


type TestProf struct {

}

func (*TestProf) StartCpuProAct(context.Context, *im_test.TestRequest, *im_test.TestRequest) error {
 profapp.StartCpuProf()
 return nil
}

func (*TestProf) StopCpuProfAct(context.Context, *im_test.TestRequest, *im_test.TestRequest) error {
 profapp.StopCpuProf()
 return nil
}


func (*TestProf) ProfGcAct(context.Context, *im_test.TestRequest, *im_test.TestRequest) error {
 profapp.ProfGc()
 return nil
}

func (*TestProf) SaveMemAct(context.Context, *im_test.TestRequest, *im_test.TestRequest) error {
 profapp.SaveMemProf()
 return nil
}

func (*TestProf) SaveBlockProfileAct(context.Context, *im_test.TestRequest, *im_test.TestRequest) error {
 profapp.SaveBlockProfile()
 return nil
}