[toc]

写在前面

pprof(性能剖析工具)是 Go 语言标准库中用于性能分析的工具。它可以帮助你了解程序在 CPU 和内存方面的性能表现,以便优化代码。使用 pprof,你可以获取 CPU 使用率、内存分配情况、阻塞情况等信息,并生成分析报告。

快速使用

使用步骤

pprof 的使用主要分为两个步骤:收集性能数据和生成分析报告。

  1. 收集性能数据:

首先,在你的 Go 代码中导入 net/http/pprof 包,并在程序中启动一个 HTTP 服务器,以便能够通过 HTTP 接口来获取性能数据。

package main

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

func main() {
    // 启动 HTTP 服务器,监听在 6060 端口
    go func() {
        http.ListenAndServe("localhost:6060", nil)
    }()

    // ... 其他代码 ...
}
  1. 生成分析报告:

在程序运行时,你可以通过访问特定的 URL 来获取性能数据,然后使用 pprof 工具生成分析报告。

  • 获取 CPU 使用率数据:

在浏览器中访问 http://localhost:6060/debug/pprof/profile,该 URL 会运行 CPU 使用率分析,运行一段时间后,下载 .pb.gz 文件,然后使用 go tool pprof 命令来查看报告。

bashCopy code
go tool pprof http://localhost:6060/debug/pprof/profile
  • 获取内存分配数据:

在浏览器中访问 http://localhost:6060/debug/pprof/heap,该 URL 会运行内存分配分析,然后下载 .pb.gz 文件,并使用 go tool pprof 命令来查看报告。

bashCopy code
go tool pprof http://localhost:6060/debug/pprof/heap

以上是基本用法,pprof 还支持更多的性能分析功能,如阻塞分析、goroutine 分析等。你可以通过访问 http://localhost:6060/debug/pprof 来获取所有支持的性能分析功能列表,并按需生成相应的报告。

注意:在生产环境中,建议避免将 pprof 暴露在公开的网络上,因为它可能泄漏敏感信息。在生产环境中,可以使用类似 net/http/pprof 提供的 mux 来进行路由管理,并通过安全手段限制访问。

参数分析

类型 描述 备注
allocs 内存分配情况的采样信息 可以用浏览器打开,但可读性不高
blocks 阻塞操作情况的采样信息 可以用浏览器打开,但可读性不高
cmdline 显示程序启动命令及参数 可以用浏览器打开,这里会显示 ./go-pprof-practice
goroutine 当前所有协程的堆栈信息 可以用浏览器打开,但可读性不高
heap 堆上内存使用情况的采样信息 可以用浏览器打开,但可读性不高
mutex 锁争用情况的采样信息 可以用浏览器打开,但可读性不高
profile CPU 占用情况的采样信息 浏览器打开会下载文件
threadcreate 系统线程创建情况的采样信息 可以用浏览器打开,但可读性不高
trace 程序运行跟踪信息 浏览器打开会下载文件,本文不涉及
  1. flat:代表“平均”,表示对应函数的执行时间或者内存占用量。
  2. flat%:代表“平均百分比”,表示对应函数占整体的百分比。
  3. sum%:代表“累积百分比”,表示对应函数及其调用链上的函数占整体的百分比。
  4. cum:代表“累积”,表示对应函数及其调用链上的函数的执行时间或者内存占用量。
  5. cum%:代表“累积百分比”,表示对应函数及其调用链上的函数占整体的百分比。

使用实例

排查 CPU 占用情况

使用命令:

go tool pprof http://172.16.12.238:8085/debug/pprof/profile

这里可能会多等一会儿

img

排除内存使用情况

go tool pprof http://http://172.16.12.238:8085/debug/pprof/heap

输入 top 命令,查看 内存占用较高的调用:

img

可以看到内存的使用情况。

我们可以给top命令加参数,例如:top20,接着我们可以使用list命令来定位具体内存消耗在哪里,入下图:

img

这里因为我没有权限,所以无法看到具体细节。

排查频繁内存回收

我们可以使用命令查看程序的GC情况:

GODEBUG=gctrace=1 ./coupert-go | grep gc

可以看到具体的GC情况。

使用命令:

go tool pprof http://172.16.12.238:8085/debug/pprof/allocs

可以看到:

img

我们可以看到这里的rawToken占用最大,我们可以可以使用```list rawToken进行定位,这里就不做演示了。

排查协程泄露

使用命令:

go tool pprof http://172.16.12.238:8085/debug/pprof/goroutine

img

具体定位我们直接使用list命令即可。

排查锁的争用

直接使用命令:

go tool pprof http://172.16.12.238:8085/debug/pprof/mutex

img

可以看到此时是没有锁的争用。

排查阻塞操作

直接使用命令:

go tool pprof http://172.16.12.238:8085/debug/pprof/block

img

可以看到此时也没有阻塞操作的。