157 lines
3.2 KiB
Markdown
157 lines
3.2 KiB
Markdown
|
# Golang Pprof 性能分析
|
|||
|
|
|||
|
pprof 是 Go 的标准性能工具,使用 net/http/pprof 或 runtime/pprof 包可以得到很好的性能记录。
|
|||
|
|
|||
|
## 1. 安装 graphviz
|
|||
|
|
|||
|
```bash
|
|||
|
apt install graphviz
|
|||
|
```
|
|||
|
|
|||
|
## 2. net/http/pprof 包
|
|||
|
|
|||
|
源码增加内容如下:
|
|||
|
|
|||
|
```go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"net/http"
|
|||
|
_ "net/http/pprof"
|
|||
|
"os"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
// 开启pprof
|
|||
|
go func() {
|
|||
|
ip := "0.0.0.0:6060"
|
|||
|
err := http.ListenAndServe(ip, nil)
|
|||
|
if err != nil {
|
|||
|
fmt.Printf("start pprof failed on %s\n", ip)
|
|||
|
os.Exit(1)
|
|||
|
}
|
|||
|
}()
|
|||
|
|
|||
|
...
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
使用浏览器打开:<http://0.0.0.0:6060/debug/pprof>
|
|||
|
|
|||
|
## 3. runtime/pprof
|
|||
|
|
|||
|
示例代码如下:
|
|||
|
|
|||
|
```go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"flag"
|
|||
|
"log"
|
|||
|
"os"
|
|||
|
"runtime/pprof"
|
|||
|
"sync"
|
|||
|
)
|
|||
|
|
|||
|
func counter() {
|
|||
|
slice := make([]int, 0)
|
|||
|
c := 1
|
|||
|
for i := 0; i < 100000; i++ {
|
|||
|
c = i + 1 + 2 + 3 + 4 + 5
|
|||
|
slice = append(slice, c)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func workOnce(wg *sync.WaitGroup) {
|
|||
|
counter()
|
|||
|
wg.Done()
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
var cpuProfile = flag.String("cpuprofile", "", "write cpu profile to file")
|
|||
|
var memProfile = flag.String("memprofile", "", "write mem profile to file")
|
|||
|
flag.Parse()
|
|||
|
//采样cpu运行状态
|
|||
|
if *cpuProfile != "" {
|
|||
|
f, err := os.Create(*cpuProfile)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
pprof.StartCPUProfile(f)
|
|||
|
defer pprof.StopCPUProfile()
|
|||
|
}
|
|||
|
|
|||
|
var wg sync.WaitGroup
|
|||
|
wg.Add(100)
|
|||
|
for i := 0; i < 100; i++ {
|
|||
|
go workOnce(&wg)
|
|||
|
}
|
|||
|
|
|||
|
wg.Wait()
|
|||
|
//采样memory状态
|
|||
|
if *memProfile != "" {
|
|||
|
f, err := os.Create(*memProfile)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
pprof.WriteHeapProfile(f)
|
|||
|
f.Close()
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
执行如下指令进行分析:
|
|||
|
|
|||
|
```bash
|
|||
|
go build main.go
|
|||
|
./main --cpuprofile=cpu.pprof
|
|||
|
./main --memprofile=mem.pprof
|
|||
|
go tool pprof cpu.pprof
|
|||
|
```
|
|||
|
|
|||
|
## 4. 字段解读
|
|||
|
|
|||
|
### 4.1. allocs
|
|||
|
|
|||
|
### 4.2. block
|
|||
|
|
|||
|
### 4.3. cmdline
|
|||
|
|
|||
|
### 4.4. goroutine
|
|||
|
|
|||
|
### 4.5. heap
|
|||
|
|
|||
|
### 4.6. mutex
|
|||
|
|
|||
|
### 4.7. profile
|
|||
|
|
|||
|
执行以下命令:
|
|||
|
|
|||
|
```bash
|
|||
|
go tool pprof -http=<listen ip>:<listen port> http://<pprof ip>:<pprof port>/debug/pprof/profile
|
|||
|
```
|
|||
|
|
|||
|
打开浏览器访问 \<listen ip\>:\<listen port\> 即可获得火焰图,CPU占用图等。
|
|||
|
|
|||
|
* Duration:程序执行时间。
|
|||
|
* pprof:命令行提示。表示当前在 go tool 的 pprof 工具命令行中,go tool 还包括 cgo、doc、pprof、test2json、trace 等多种命令
|
|||
|
* top:pprof 的指令之一,显示 pprof 文件中的前 10 项数据,可以通过 top 20 等方式显示 20 行数据;当然 pprof 下有很多指令,例如 list,pdf、eog 等等
|
|||
|
* flat/flat%:分别表示在当前层级 cpu 的占用时间和百分比。
|
|||
|
* cum/cum%:分别表示截止到当前层级累积的 cpu 时间和占比。
|
|||
|
* sum%:所有层级的 cpu 时间累积占用,从小到大一直累积到 100%。
|
|||
|
|
|||
|
### 4.8. threadcreate
|
|||
|
|
|||
|
### 4.9. trace
|
|||
|
|
|||
|
执行以下命令:
|
|||
|
|
|||
|
```bash
|
|||
|
go tool trace -http=<listen ip>:<listen port> http://<pprof ip>:<pprof port>/debug/pprof/trace
|
|||
|
```
|
|||
|
|
|||
|
打开浏览器访问 \<listen ip\>:\<listen port\> 即可获得 trace 图。
|
|||
|
|
|||
|
### 4.10. full goroutine stack dump
|