目录
一、pprof 包
使用pprof,需要导入 "net/http/pprof" 包:
_ "net/http/pprof"
相当于给当前程序的http服务器多注册了几个接口:
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)
对于接口服务,可以压测接口,分析函数耗时。
对于非接口服务,可以额外开一个协程来注册服务器,分析程序的耗时。
二、通过开启 pprof web 服务分析性能
1、导入 pprof 包,开启 pprof 的web服务,启动程序
import (
"github.com/gin-gonic/gin"
"log"
"net/http"
_ "net/http/pprof" // 导入pprof
)
func main() {
go func() {
log.Fatal(http.ListenAndServe(":8080", nil)) // 启动pprof服务
}()
r := gin.New()
r.Run(":9090")
}
2、对于接口性能测试,可以使用wrk进行压测:(https://github.com/wg/wrk 或 https://github.com/adjust/go-wrk)
go-wrk -n 50000 http://localhost:8080/test
3、使用 pprof 包自带的非图形化分析
访问 http://localhost:8080/debug/pprof,可以查看相关性能参数,但是这里不是图形化的,看起来不直观。
4、使用 go tool pprof 工具进行可视化分析
下载安装 Graphviz,windows下载.msi格式文件进行安装。
命令行运行以下各命令开启web服务可进行不同维度的性能分析,可以 top、tree 树形图、flame 火焰图等多种方式分析。
其中,profile的分析需要设置总采样时间,不设置的话默认是30s,采样频率默认是100,即10ms。
- cpu分析
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/profile
go tool pprof -seconds=30 -http=:9090 http://localhost:8080/debug/pprof/profile
- goroutine分析
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/goroutine
- allcos分析
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/allcos
- heap分析
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/heap
- mutex分析
go tool pprof -http=:9090 http://localhost:8080/debug/pprof/mutex
5、使用 go-torch 工具进行可视化分析
另外,除了 go tool pprof 工具之外,还可以使用 go-torch 来生成火焰图
压测的同时,另开终端执行:
go-torch -u http://localhost:8080 -t 30
30s之后终端会出现 Writing svg to torch.svg,然后使用浏览器打开 torch.svg 就可以看到火焰图
y轴表示函数执行顺序。
x轴代表每个采样周期时间内,函数执行时间占比,越宽代表占据cpu时间越多。
可以找出耗时的函数,然后不断优化代码。
三、通过导出 pprof 文件分析性能
1、采样,生成 cpu.pprof 文件和 mem.pprof 文件
// cpu采样
f, err := os.Create(*cpuprofile)
//...
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// mem采样
f, err := os.Create(*memprofile)
pprof.WriteHeapProfile(f)
f.Close()
//...
2、生成文件
go tool pprof cpu.pprof
go tool pprof mem.pprof
参考
Go程序性能分析工具和方法 - SegmentFault 思否
Golang程序性能分析(一)pprof和go-torch - 知乎
Go 服务进行自动采样性能分析的方案设计与实现|go|内存|路由|pprof
四、GC监控和优化
1、识别内存泄漏
- 内存使用量不断增加:在多次采样之间,内存使用量持续增加,而不是趋于稳定或减少。
- 大量未释放的内存:在火焰图中,某些函数持续显示高内存分配,这可能表明内存没有被正确释放。
2、优化代码减少内存分配或确保及时释放内存
- 使用对象池:对于频繁创建和销毁的对象,使用对象池可以减少内存分配
- 优化数据结构:减少不必要的内存使用,例如使用更紧凑的数据结构
- 确保资源清理:确保在不再需要时清理资源,例如关闭 channel、停止定时器等
参考
五、典型问题
死锁、通道阻塞:调整锁
内存泄漏、goroutine泄漏:控制并发量、设置超时
cpu打满、内存打满:调节gc时间、更换json库、优化最耗时的方法
客户端 time-wait 过多:增大连接池
六、trace 包
go tool pprof
用于分析 CPU 和内存使用情况。
go tool trace
用于查看由 runtime/trace
生成的 trace
文件,提供详细的执行时间线信息。
package main
import (
"os"
"runtime/trace"
)
func main() {
f, _ := os.Create("trace.out")
defer f.Close()
_ = trace.Start(f)
defer trace.Stop()
// your code
}
编译并运行这个程序:
go run main.go
然后在当前目录下将生成一个 trace.out
文件。然后使用 go tool trace
查看这个文件:
go tool trace trace.out
将会启动一个本地 Web 服务器,并在浏览器中打开一个交互式的界面,可以通过这个界面查看详细的跟踪信息。