使用pprof做性能分析
一、如果程序是一次性执行的,比如分析一段数据,完成了退出的程序,可以使用 runtime/pprof库来分析程序性能
1、分析CPU性能
f, err := os.Create("cpuprofile") … defer pprof.StopCPUProfile() |
2、分析内存消耗
f,err :=os.Create("memprofile") … err:=pprof.WriteHeapProfile(f) |
3、分许生成的文件
go tool pprof memprofile |
进入pprof指令
1)top
可以看到占用排名的参数等
2)web
使用web页面查看, 需要安装 graphviz先
sudo apt install graphviz |
二、服务型的应用比如web服务器,则使用http/pprof来进行性能分析
因为在项目中用到了gin框架,所以直接使用
github.com/gin-contrib/pprof |
来完成。
示例代码:
package main import ( "net/http" "github.com/gin-contrib/pprof" "github.com/gin-gonic/gin" ) func main() { app := gin.Default() pprof.Register(app) app.GET("pproftest", func(c *gin.Context) { c.String(http.StatusOK, "pprof test") }) app.Run(":10100") } |
可以看到pprof提供了很多个接口可以直接访问:
[GIN-debug] GET /debug/pprof/ --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/cmdline --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/profile --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] POST /debug/pprof/symbol --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/symbol --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/trace --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/allocs --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/block --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/goroutine --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/heap --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/mutex --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /debug/pprof/threadcreate --> github.com/gin-contrib/pprof.pprofHandler.func1 (3 handlers) [GIN-debug] GET /pproftest --> main.main.func1 (3 handlers) [GIN-debug] Listening and serving HTTP on :10100 |
使用pprof来采集数据
1)获取20s内的cpu信息
go tool pprof --seconds 20 http://localhost:10100:/debug/pprof/profile |
生成文件:
Saved profile in /home/cc/pprof/pprof.main.samples.cpu.001.pb.gz
如果想采集内存的使用情况:
go tool pprof --seconds 20 http://localhost:10100/debug/pprof/heap
Saved profile in /home/cc/pprof/pprof.bench.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz
在采集信息的同时使用wrk模拟请求:
wrk -t2 -c100 -d30s http://localhost:10100/pproftest
2)生成详细的web信息(选择对应生成的文件):
go tool pprof -http localhost:10102 /home/cc/pprof/pprof.main.samples.cpu.001.pb.gz |
通过web界面可以看到
调用链以及资源使用情况:
火焰图:
x轴表示占用CPU占用时间,y轴表示调用先后
其他:
1)/debug/pprof/profile:访问这个链接会自动进行 CPU profiling,持续 30s,并生成一个文件供下载
2)/debug/pprof/heap: Memory Profiling 的路径,访问这个链接会得到一个内存 Profiling 结果的文件
3)/debug/pprof/block:block Profiling 的路径
4)/debug/pprof/goroutines:运行的 goroutines 列表,以及调用关系
go语言的benchmark
1、怎么使用go的benchmark
1)待测试函数(misc.go):
package main
func sum(n int) int {
var sum int
for i := 0; i < n; {
sum += i
i += 1
if sum > 100000 {
break
}
}
return sum
}
2)测试文件(misc_test.go):
package main
import (
"testing"
)
func BenchmarkSum(b *testing.B) {
for n := 0; n < b.N; n++ {
sum(n)
}
}
a)函数名一般为BenchmarkFunc(b *testing.B) Func为被测试函数
b)b.N是运行次数,一般由go根据系统决定
c)传进去的参数是 *testing.B
3)测试。
单元测试是go test `path` 但是benchmark需要带上 -bench参数来运行benchmark
其中 BenchmarkMulti-4表示GOMAXPROCS的值 ,后面是执行次数以及每次执行消耗的时间
指定benchmark时间:
指定benchmark次数:
查看benchmark的内存分配情况
cpu profile
也可结合工具生成火焰图进行分析。
benchmark结合pprof使用:
1、生成pprof文件
go test -bench . -cpuprofile=cpu.pprof
2、分析
go tool pprof -web cpu.pprof