pprof 是 golang 官方提供的性能调优分析工具,可以对程序进行性能分析,并可视化数据,看起来相当的直观。 当你的 go 程序遇到性能瓶颈时,可以使用这个工具来进行调试并优化程序。


安装pprof工具

1
go get -u github.com/google/pprof

web程序代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

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

    "github.com/fvbock/endless"
    "github.com/gin-gonic/gin"
)

func main() {
    gin.SetMode(gin.DebugMode)
    r := gin.Default()

    w := sync.WaitGroup{}
    w.Add(2)
    go func() {
        endless.ListenAndServe("127.0.0.1:6060", nil)
        w.Done()
    }()

    go func() {
        endless.ListenAndServe("127.0.0.1:6061", r)
        w.Done()
    }()

    w.Wait()
}

Web监控

浏览器访问:http://127.0.0.1:6060/debug/pprof/

grafana

压力测试

安装go-wrk

1
go install github.com/tsliwowicz/go-wrk@latest

基本使用

使用 80 个 Go 协程(连接)运行60 秒钟的基准测试:

1
go-wrk -M POST -body 'DFTNARmZh1G3kYl1bkmctF1LS6nop8CrJq5CjxXa/7dqpEzwU2S8QzxIK+5V31B+G3WnztRXYW/XEetTMKFZBRaAMjsj1k4cCI8pP8ptzFJ58gMkbf0jXNIntRnQCVGH0FGwnSWAmacW4QuyhdqexFq3EqccM2K45PLSjLu3KqoQDHdogOgR4tBTu03Rkd6rHd8WESytRVjt+2kNBvnr9w==' -c 80 -d 60 http://127.0.0.1:6061/api/store/country

命令行采样分析

CPU 性能分析

runtime 每隔 10 ms 中断一次,记录此时正在运行的 goroutines 的堆栈信息

1
go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=60

grafana

常用命令 top n : n 不写默认显示 10 个占用 CPU 时间最多的函数 top -cum:将数据累计查看各个函数 CPU 占用。 tree:树形结构查看 goroutine 情况。 list 方法名:查看方法名里面具体调用耗时时长。 web:生成 SVG 函数调用图(需安装 graphviz)。

内存性能分析

记录堆内存分配时的堆栈信息,忽略栈内存分配信息,默认每 1000 次采样 1 次

1
go tool pprof http://127.0.0.1:6060/debug/pprof/heap?seconds=60

阻塞性能分析

记录一个协程等待一个共享资源花费的时间

锁性能分析

记录因为锁竞争导致的等待或延时

分析数据

安装graphviz

1
yum -y install graphviz

生成火焰图

y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,底部就是正在执行的函数,上方都是它的父函数。 x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。 火焰图就是看底层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题。

1
2
go tool pprof -http=0.0.0.0:18089 /root/pprof/pprof.main.samples.cpu.005.pb.gz
Serving web UI on http://0.0.0.0:18089

grafana