答案: 采用go内置的runtime/pprof包, 和go tool pprof。
分三个步骤:
1. 在main函数中,增加性能分析代码:()
f, err := os.Create(cpuProfile)
if err != nil {
log.Errorf("create proc file:%v failed.", cpuProfile)
return
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
其中cpuProfile是用来存储性能分析数据的文件。
2. 在main函数中,设置一种方法,能够让main函数自然退出,从而调用 defer pprof.StopCPUProfile() 这行代码。只有调用这行代码,才能生成prof文件。注意, 这是最关键的一步。
推荐的main函数自然退出方法,是:
svr, err = server.NewServer(log)
if err != nil {
log.Errorf("create server failed. err:%v", err)
return
}
sc := make(chan os.Signal, 1)
signal.Notify(sc,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT,
syscall.SIGUSR1)
go func() {
for {
sig := <-sc
log.Errorf("got signal:%v and exit.", sig)
svr.Close()
break
}
}()
svr.Run(log)
svr.Close() 用来让 svr.Run(log) 优雅退出。 这两个函数的实现可以如下:
func (s *Server) Close() {
s.running = false
if s.listener != nil {
s.listener.Close()
}
}
func (s *Server) Run(log *ulog.BuLogger) error {
s.running = true
for s.running {
//do something
}
return nil
}
3. 运行模块, 运行前注意要设置 prof文件的保存地址, 既设置cpuProfile这个变量。模块运行后,会生成cpuProfile对应的文件,但文件内容为空。
4. 运行一段时间后, 采用命令: kill -2 $pid 让模块进程自然终止。 自然终止后,cpuProfile对应的文件有内容。
5. cpuProfile文件中的内容是二进制的,不可直接阅读。此时,可以转化为pdf格式。转化的方法:
5.1 先下载graphviz这款工具:
apt-get install graphviz
5.2 使用go tool pprof 命令,将cpuProfile文件转化为pdf文件:
go tool pprof -pdf 你的模块名称 cpuProfile文件地址 > pdf文件地址
比如:
go tool pprof -pdf ./uddb_router cpu.pprof > report.pdf
6. 转化成pdf格式后,就可以直接用pdf阅读器打开看了。效果如下: