Go 语言性能测试

本文来学习一下如何进行 Go 语言的性能测试。这里需要学习一个 Go 语言官方提供的工具 pprof:

  • runtime/pprof:采集程序(非 Server)的运行数据进行分析;
  • net/http/pprof:采集 HTTP Server 的运行时数据进行分析。

上述两个包的底层实现是一样的,一般建议直接在主函数上加上 http 服务而使用第二个包,毕竟可视化显示易于观察和操作。故本文仅介绍 net/http/pprof 的用法。

1. pprof 使用方法

直接在程序入口,也就是 main 函数所在的文件中导入 pprof。

 import _ "net/http/pprof"

示例代码如下:

package main

import (
    "fmt"
    "net/http"
    _ "net/http/pprof"
    "time"
)

func main() {
    //打印数字
    go printNum()
    //打印字符
    go printChar()
    http.ListenAndServe("0.0.0.0:9300", nil)//启动一个服务用于查看性能分析可视化页面
}
func printChar() {
    for i := '0'; ; i++ {
        fmt.Println("printChar:", string(i))
        time.Sleep(time.Second)
    }
}
func printNum() {
    for i := 0; ; i++ {
        fmt.Println("printNum:", i)
        time.Sleep(time.Second)
    }
}

上述代码启动,pprof 会在这个服务上自动创建路由:

debug/pprof/

在浏览器中输入127.0.0.1:9300/debug/pprof/,会出现如下页面:

图片描述

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

  • allocs:内存分配情况;
  • block:获取导致阻塞的 goroutine 堆栈(如 channel, mutex 等);
  • cmdline:当前程序激活的命令行启动参数;
  • goroutine:当前当前运行的 goroutine 的堆栈信息;
  • heap:存活对象的内存分配情况;
  • mutex :互斥锁的竞争持有者的堆栈跟踪;
  • profile:默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件;
  • threadcreate:操作系统线程跟踪;
  • trace:得到一个分析用的 trace 文件。

2. 使用工具分析 profile 和 trace

当在127.0.0.1:9300/debug/pprof/中点击 profile 和 trace 时会分别得到一个文件,我们可以使用 Go 语言自带的工具对这两个文件进行解析。在解析之前,需要编译得到程序代码的可执行文件,配合分析文件使用。

2.1 解析 profile

使用如下命令行进入解析页面:

go tool pprof .firstgo.exe .profile

执行结果:

图片描述

如上如所示,我们进入了 pprof 的命令行界面,可以输入top来查看前 10 行数的 CPU 占用情况:

图片描述

  • flat:采样频率(10ms);
  • flat%:采样频率(10ms)下,CPU 运行耗时总比例;
  • sum%:给定函数累积使用 CPU 总比例,如第二行 sum% =40.00% = 20.00% + 20.00%;
  • cum:当前函数加上它之上的调用运行总耗时,包括函数等待子函数返回;
  • cum%:CPU 运行耗时总比例;
  • 最后一列为函数名称。

还可使用 help 指令来查看 pprof 所有操作,读者可以自行探索。

2.2 解析 trace

使用如下命令解析 trace 文件:

go tool trace .firstgo.exe  .trace

此时会自动打开一个 web 页面:

图片描述

  • View trace:查看跟踪;
  • Goroutine analysis:Goroutine 分析;
  • Network blocking profile:网络阻塞概况;
  • Synchronization blocking profile:同步阻塞概况;
  • Syscall blocking profile:系统调用阻塞概况;
  • Scheduler latency profile:调度延迟概况;
  • User defined tasks:用户自定义任务;
  • User defined regions:用户自定义区域;
  • Minimum mutator utilization:最低 Mutator 利用率。

我们可以看到有的链接后面跟着(),是因为这些链接的使用需要配合第三方工具,可以点进去查看缺失的内容,下载安装后就可以使用了,一般使用前两个就可以分析程序的执行情况了。

3. 小结

本文主要介绍了 Go 语言自带的工具 pprof 的用法,以及其生成分析文件的解析。需要注意的是每个分析文件都要配合这个程序的可执行文件使用。还有就是建议大家在开发过程中尽量时不时的用一下 pprof,可以使开发出来的程序更稳定更高效。