1.8 Go 性能测试工具PProf

Go语言自带了强大的性能测试工具pprof,位于 net/http 包下的 pprof。 官方文档

PProf 关注的模块

  • CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
  • Memory Profile(Heap Profile):报告程序的内存使用情况
  • Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
  • Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的

PProf 使用方式

PProf 主要涉及两个包:”net/http/pprof”、”runtime/pprof”。

net/http/pprof:只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来。使用 net/http/pprof 可以做到直接看到当前 web 服务的状态,包括 CPU 占用情况和内存使用情况等。如果服务是一直运行的,如 web 应用,可以很方便的使用第一种方式 import "net/http/pprof"

runtime/pprof:可以用来产生 dump 文件,再使用 Go Tool PProf 来分析这运行日志。

引入示例:

  1. #web服务器:
  2. import (
  3. "net/http"
  4. _ "net/http/pprof"
  5. )
  6. #一般应用程序(实际应用无web交互)
  7. import (
  8. "net/http"
  9. _ "runtime/pprof"
  10. )

下面主要介绍web收集PProf信息方式

使用示例:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. _ "net/http/pprof"
  7. "time"
  8. )
  9. func sayHelloHandler(w http.ResponseWriter, r *http.Request) {
  10. hellowold(10000)
  11. fmt.Println("path", r.URL.Path)
  12. fmt.Println("scheme", r.URL.Scheme)
  13. fmt.Fprintf(w, "Hello world!\n") //这个写入到w的是输出到客户端的
  14. }
  15. func main() {
  16. http.HandleFunc("/", sayHelloHandler) // 设置访问路由
  17. log.Fatal(http.ListenAndServe(":8080", nil))
  18. }
  19. func hellowold(times int) {
  20. time.Sleep(time.Second)
  21. var counter int
  22. for i := 0; i < times; i++ {
  23. for j := 0; j < times; j++ {
  24. counter++
  25. }
  26. }
  27. }

访问:http://127.0.0.1:8080/debug/pprof/

输出:

  1. /debug/pprof/
  2. profiles:
  3. 0 block
  4. 4 goroutine
  5. 2 heap
  6. 0 mutex
  7. 5 threadcreate
  8. full goroutine stack dump

这个路径下还有几个子页面:

  • /debug/pprof/profile:访问这个链接会自动进行 CPU profiling,持续 30s,并生成一个文件供下载。

  • /debug/pprof/cmdline 获取程序启动时的命令及参数。

  • /debug/pprof/symbol 根据传入的程序计数器(PC)的值,获取对应的函数的名称信息,调用了runtime包的FuncForPC获取对应的函数信息。可以传入多个PC值,以加号作为连接符号,比如访问:http://127.0.0.1:8080/debug/pprof/symbol?0x4e667d+0x6ec770, 返回PC值与函数对应名称的信息。

  • /debug/pprof/trace 此接口用于获取程序执行中的事件跟踪信息,比如协程、系统调用、GC、堆大小改变等事件,大多数事件的跟踪精确度能达到纳秒级别,后端调用了runtime包的StartTrace,会进行一个STW的操作。获取数据的时长默认为1秒,可以通过seconds参数进行修改。先通过以下命令获取数据:

    wget http://127.0.0.1:8080/debug/pprof/trace?seconds=10 -O tracefile

    然后执行go tool trace tacefile进行数据分析。

  • /debug/pprof/block:block Profiling 的路径。

  • /debug/pprof/goroutines:运行的 goroutines 列表,以及调用关系。

  • /debug/pprof/heap: Memory Profiling 的路径,访问这个链接会得到一个内存 Profiling 结果的文件。

  • /debug/pprof/threadcreate查看线程创建信息。

Go tool pprof 分析工具(图形工具graphviz为例)

Go Tool PProf 工具可以对以上链接下载的 prof 文件进行更详细的分析,可以生成调用关系图和火焰图。

centos 7.5 下安装graphviz

  1. yum install 'graphviz*' --skip-broken

—skip-broken可选:跳过错误依赖,不加这个参数会提示安装包依赖错误,因为这里并不需要其它的安装包,所以跳过即可。

其他系统安装方式可参考:官网

Go tool pprof常用基本调试基本命令(默认30s采集时间,可通过—seconds)

下面以cpu信息分析为例:

通过执行

  1. go tool pprof --text http://127.0.0.1:8080/debug/pprof/profile

生成profile压缩gz文件(一般在/root/pprof目录下的.gz),选择文件进入交互,或执行一下命令(注意:执行的过程,访问一下http://localhost:8080/,这样会得到相应的监测数据)

  1. go tool pprof http://localhost:8080/debug/pprof/profile
  2. Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile
  3. Saved profile in /root/pprof/pprof.main.samples.cpu.002.pb.gz
  4. File: main
  5. Type: cpu
  6. Time: Dec 14, 2018 at 3:26pm (CST)
  7. Duration: 30s, Total samples = 60ms ( 0.2%)
  8. Entering interactive mode (type "help" for commands, "o" for options)
  9. (pprof)

输入top

  1. (pprof) top
  2. Showing nodes accounting for 60ms, 100% of 60ms total
  3. flat flat% sum% cum cum%
  4. 60ms 100% 100% 60ms 100% main.hellowold /home/go/src/example/main.go
  5. 0 0% 100% 60ms 100% main.sayHelloHandler /home/go/src/example/main.go
  6. 0 0% 100% 60ms 100% net/http.(*ServeMux).ServeHTTP /usr/lib/golang/src/net/http/server.go
  7. 0 0% 100% 60ms 100% net/http.(*conn).serve /usr/lib/golang/src/net/http/server.go
  8. 0 0% 100% 60ms 100% net/http.HandlerFunc.ServeHTTP /usr/lib/golang/src/net/http/server.go
  9. 0 0% 100% 60ms 100% net/http.serverHandler.ServeHTTP /usr/lib/golang/src/net/http/server.go
  10. (pprof)

可以看到 main.hellowold 是用cpu最多。

输入 web #生成调用关系图

Go 性能测试工具PProf - 图1

如查看历史调试文件信息,通过指定的profile文件进入(pprof)即可:

例如:

go tool pprof /root/pprof/pprof.main.samples.cpu.001.pb.gz File: main Type: cpu Time: Dec 14, 2018 at 11:37am (CST) Duration: 29.99s, Total samples = 0 Entering interactive mode (type “help” for commands, “o” for options) (pprof)

如果想查看pprof其他命令,可输入help。

生成火焰图 (官方:https://github.com/uber/go-torch)

从Go 1.11开始,火焰图形可视化go tool pprof直接可用!

  1. # This will listen on :8081 and open a browser.
  2. # Change :8081 to a port of your choice.
  3. $ go tool pprof -http=":8081" [binary] [profile]

如果你不能使用Go 1.11,你可以获得最新的pprof工具并使用它:

  1. # Get the pprof tool directly
  2. $ go get -u github.com/google/pprof
  3. $ pprof -http=":8081" [binary] [profile]

我的golang 版本 v 1.11,所以只执行以下命令:(注意:在执行以下命令过程,访问一下http://localhost:8080/,消耗以下性能)

  1. go tool pprof -http=":8081" http://localhost:8080/debug/pprof/profile
  2. Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile
  3. Saved profile in /root/pprof/pprof.main.samples.cpu.007.pb.gz

过一会儿会产生个web窗口

Go 性能测试工具PProf - 图2

选择 VIEW->Flame Graph 得到火焰图形

Go 性能测试工具PProf - 图3

links