Home / PostsPost
Goland pprof 火焰图
嘟噜聪2023/03/02 15:35:32 [Golang] [pprof] [火焰图] [性能分析] [工具] [go tools] 1232人已阅
简介 > Golang的pprof是一个性能分析工具,可以用于分析程序的CPU、内存使用情况等,可以帮助我们快速定位代码中的性能瓶颈。![](http://source.qiniu.cnd.nsin
Golang的pprof是一个性能分析工具,可以用于分析程序的CPU、内存使用情况等,可以帮助我们快速定位代码中的性能瓶颈。
pprof提供了两种类型的性能分析:CPU profile和Memory profile。
CPU profile
通过捕捉一段时间内的CPU使用情况来生成CPU profile。我们可以使用go tool pprof
命令对生成的profile文件进行分析。
生成CPU profile的步骤如下:
import (
"log"
"os"
"runtime/pprof"
)
func main() {
f, err := os.Create("cpuprofile")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal(err)
}
defer pprof.StopCPUProfile()
// 程序代码
}
在程序运行过程中,pprof会将CPU的使用情况记录到cpuprofile文件中。当我们需要分析程序性能时,可以使用以下命令:
$ go tool pprof -http=:8080 cpuprofile
这个命令会启动一个Web服务,我们可以在浏览器中访问http://localhost:8080
来进行可视化分析。
Memory profile
生成Memory profile的步骤如下:
import (
"log"
"os"
"runtime/pprof"
)
func main() {
f, err := os.Create("memprofile")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal(err)
}
// 程序代码
}
在程序运行过程中,pprof会将内存的分配情况记录到memprofile文件中。当我们需要分析程序内存使用时,可以使用以下命令:
$ go tool pprof -http=:8080 memprofile
这个命令同样会启动一个Web服务,我们可以在浏览器中访问http://localhost:8080
来进行可视化分析。
除了命令行工具外,pprof还提供了一些API供程序中使用,比如可以通过调用runtime/pprof
包中的一些函数来生成profile
文件,也可以通过调用http/pprof
包中的API来实现Web接口,方便远程获取程序的性能数据。
runtime/pprof部分功能介绍
pprof是Golang标准库中的一个性能分析工具,提供了很多API供程序使用,方便对程序的性能进行分析和优化。
func StartCPUProfile(w io.Writer) error
StartCPUProfile
用来开始CPU的性能分析,将CPU的性能数据写入一个指定的文件中。参数w是一个io.Writer
接口类型的变量,可以指定将CPU性能数据写入到哪个文件中。func StopCPUProfile()
StopCPUProfile
用来停止CPU的性能分析,并将收集到的性能数据写入到上面指定的文件中。func Lookup(symbol string) *Profile
Lookup用来查找指定的性能分析数据,可以通过指定符号(symbol)的方式查找。func WriteHeapProfile(w io.Writer) error
WriteHeapProfile
用来写入堆内存分析的性能数据,将收集到的数据写入一个指定的文件中。func WriteProfile(p *Profile, name string) error
WriteProfile
用来将指定的性能分析数据写入到指定的文件中。
这些API可以方便地对程序进行性能分析,可以通过手动触发分析数据的收集,并将分析数据写入文件中,然后通过pprof工具进行分析。此外,pprof还提供了一些其他的API,如通过HTTP接口获取性能分析数据等,方便程序进行集成。
通过HTTP接口获取数据
如果在 HTTP 服务中引用了 runtime/pprof
包,并启用了 pprof
收集器,那么你可以通过以下步骤来访问 pprof 数据:
- 在 HTTP 服务中注册 pprof 的 HTTP 处理函数,这个函数会将 pprof 数据暴露给外部请求:
import (
"net/http"
_ "net/http/pprof" // 导入 pprof 包,执行包初始化函数,注册 pprof 处理函数
)
func main() {
// 注册 HTTP 路由处理函数
http.HandleFunc("/", myHandler)
// 注册 pprof 处理函数
http.HandleFunc("/debug/pprof/", pprof.Index)
// 启动 HTTP 服务
http.ListenAndServe(":8080", nil)
}
上面代码中,我们通过 _ "net/http/pprof"
导入了 net/http/pprof
包,并通过 pprof.Index
函数注册了 pprof 的 HTTP 处理函数,将其绑定到了 /debug/pprof/
路径上。
- 访问 pprof 数据
在浏览器中访问 http://localhost:8080/debug/pprof/
即可进入 pprof 的 web 页面,浏览器会显示出所有可用的 pprof 数据类型,包括 heap
、goroutine
、threadcreate
、block
、mutex
等。我们可以点击其中任意一个类型,然后通过相应的页面进行数据分析。
如果需要在程序代码中访问 pprof
可以使用 http/pprof
包提供的接口来访问 runtime/pprof
提供的性能分析数据。http/pprof
包默认会注册以下路由:
/debug/pprof/
: 显示当前进程的所有性能分析数据链接。/debug/pprof/cmdline
: 显示进程启动命令行参数。/debug/pprof/profile
: 返回 CPU Profiling 数据。/debug/pprof/heap
: 返回堆内存分配数据。/debug/pprof/block
: 返回阻塞事件数据。/debug/pprof/mutex
: 返回互斥锁的竞争关系数据。
通过访问这些路由,就可以获取到相应的性能分析数据。例如,访问 /debug/pprof/profile
就可以获取到 CPU Profiling 数据。
同时,http/pprof
包也提供了一些方法来注册这些路由。例如,http/pprof
包提供了 http.HandleFunc
方法来注册处理 /debug/pprof/
路由的回调函数。代码示例如下:
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
// 启动 http 服务,注册 pprof 相关路由
go func() {
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}()
// TODO: 启动你的应用服务
// ...
}
上面的代码中,我们通过使用 _ "net/http/pprof"
的方式来注册了 http/pprof
包提供的路由。然后通过 http.ListenAndServe
方法来启动一个 http 服务,提供对性能分析数据的访问。这里我们没有指定处理函数,所以会使用 http.DefaultServeMux
,即使用 http/pprof
包默认注册的处理函数。
这样,我们就可以通过访问 http://localhost:8080/debug/pprof/
来获取当前进程的所有性能分析数据链接,以及访问其他的路由来获取相应的性能分析数据。
很赞哦! (9)