2020-03-19

2020-03-21  本文已影响0人  northking

1. 概述

在 go 语言中,主要关注的应用运行情况主要包括以下几种:

1.1 pprof

PProf是一个CPU分析器( cpu profiler), 它是gperftools工具的一个组件, 由Google工程师为分析多线程的程序所开发,是用于可视化和分析性能分析数据的工具

pprof 以 profile.proto 读取分析样本的集合,并生成报告以可视化并帮助分析数据(支持文本和图形报告)

profile.proto 是一个 Protocol Buffer v3 的描述文件,它描述了一组 callstack 和 symbolization 信息, 作用是表示统计分析的一组采样的调用栈,是很常见的 stacktrace 配置文件格式

1.2 支持什么使用模式

2 安装依赖工具:

1) 安装 PProf

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

2) 安装 FlameGraph

cd $WORK_PATH 
git clone https://github.com/brendangregg/FlameGraph.git
export PATH=$PATH:$WORK_PATH/FlameGraph

3)安装 graphviz
pprof生成的prof文件时二进制的,需要把这个二进制的文件转换为我们人类可读的,graphviz可以帮助我们把二进制的prof文件转换为图像

brew install graphviz 

3 采集、分析数据

做 Profiling 第一步就是怎么获取应用程序的运行情况数据。go 语言提供了两个库:

核心工具是:go tool pprof 命令:获取和分析 Profiling 数据

更详细的 pprof 使用方法可以参考 pprof --help 或者 pprof 文档

对于不同类型的应该也有不同的采集和分析方式

3.1 工具型应用

3.1.1 脚本类

如果你的应用是一次性的,运行一段时间就结束。那么最好的办法,就是在应用退出的时候把 profiling 的报告保存到文件中,进行分析。对于这种情况,可以使用 runtime/pprof

pprof 封装了很好的接口供我们使用,比如要想进行 CPU Profiling,可以调用 pprof.StartCPUProfile() 方法,它会对当前应用程序进行 CPU profiling,并写入到提供的参数中(w io.Writer),要停止调用 StopCPUProfile() 即可。

示例:

import (
    "os"
    "runtime/pprof"
)
func main() {
    f, _ := os.Create("cpu.prof")
    defer f.Close()

    do somethings...

    pprof.StopCPUProfile()
}

应用执行结束后,就会生成一个文件(cpu.prof),保存了我们的 CPU profiling 数据。

想要获得内存的数据,直接使用 WriteHeapProfile 就行,不用 startstop 这两个步骤了:

f, err := os.Create(*memprofile)
pprof.WriteHeapProfile(f)f.Close()

3.1.2 通过测试用例进行性能测试

编写测试用例

(1)新建 data/d_test.go,文件内容:

package data
 
import "testing"
 
const url = "https://github.com/EDDYCJY"
 
func TestAdd(t *testing.T) {
    s := Add(url)
    if s == "" {
        t.Errorf("Test.Add error!")
    }
}
 
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(url)
    }
}

(2)执行测试用例,生成prof文件

$go test -bench=. -cpuprofile=cpu.prof

pkg: github.com/EDDYCJY/go-pprof-example/data

BenchmarkAdd-410000000187ns/op

PASS

ok      github.com/EDDYCJY/go-pprof-example/data2.300s

-memprofile 也可以了解一下

启动 PProf 可视化界面

$go tool pprof -http=:8080 cpu.prof

3.2 服务型应用(web服务)

3.2.1 引入

如果你的应用是一直运行的,比如 web 应用,那么可以使用 net/http/pprof 库,它能够在提供 HTTP 服务进行分析。

import中只需要添加一行:

import _ "net/http/pprof"

main函数中启动监听:

go func() {
    if err := http.ListenAndServe(fmt.Sprintf("%s:%s", "0.0.0.0", "6060"), nil); nil != err {
            panic(err)
        }
    }()

3.2.2 分析数据

3.2.2.1 通过 Web 界面

查看当前总览:访问 http://127.0.0.1:6060/debug/pprof/

/debug/pprof/
 
profiles:
0    block
5    goroutine
3    heap
0    mutex
9    threadcreate
 
full goroutine stack dump

这个页面中有许多子页面,咱们继续深究下去,看看可以得到什么?

pprof监控的内容项目入下表所示。

3.2.2.1 通过交互式终端使用

能通过对应的库获取想要的 Profiling 数据之后(不管是文件还是 http),下一步就是要对这些数据进行保存和分析,我们可以使用 go tool pprof 命令行工具。
(1)go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60

$ go tool pprof http://localhost:6060/debug/pprof/profile\?seconds\=60

Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=60

Saved profilein/Users/eddycjy/pprof/pprof.samples.cpu.007.pb.gz

Type: cpu

Duration: 1mins, Total samples = 26.55s (44.15%)

Entering interactive mode (type"help"forcommands,"o"foroptions)

(pprof)

执行该命令后,需等待 60 秒(可调整 seconds 的值),pprof 会进行 CPU Profiling。结束后将默认进入 pprof 的交互式命令模式,可以对分析的结果进行查看或导出。具体可执行 pprof help 查看命令说明

(pprof) top10

Showing nodes accountingfor25.92s, 97.63% of 26.55s total

Dropped 85 nodes (cum <= 0.13s)

Showing top 10 nodes out of 21

      flat  flat%  sum%        cum  cum%

    23.28s 87.68% 87.68%    23.29s 87.72%  syscall.Syscall

    0.77s  2.90% 90.58%      0.77s  2.90%  runtime.memmove

    0.58s  2.18% 92.77%      0.58s  2.18%  runtime.freedefer

    0.53s  2.00% 94.76%      1.42s  5.35%  runtime.scanobject

    0.36s  1.36% 96.12%      0.39s  1.47%  runtime.heapBitsForObject

    0.35s  1.32% 97.44%      0.45s  1.69%  runtime.greyobject

    0.02s 0.075% 97.51%    24.96s 94.01%  main.main.func1

    0.01s 0.038% 97.55%    23.91s 90.06%  os.(*File).Write

    0.01s 0.038% 97.59%      0.19s  0.72%  runtime.mallocgc

    0.01s 0.038% 97.63%    23.30s 87.76%  syscall.Write

最后一列为函数名称,在大多数的情况下,我们可以通过这五列得出一个应用程序的运行情况,加以优化

pprof 不仅能打印出最耗时的地方(top),还能列出函数代码以及对应的取样数据(list)、汇编代码以及对应的取样数据(disasm),而且能以各种样式进行输出,比如 svg、gv、callgrind、png、gif等等

(2)go tool pprof http://localhost:6060/debug/pprof/heap

$ go tool pprof http://localhost:6060/debug/pprof/heap

Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap

Saved profilein/Users/eddycjy/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.008.pb.gz

Type: inuse_space

Entering interactive mode (type"help"forcommands,"o"foroptions)

(pprof) top

Showing nodes accountingfor837.48MB, 100% of 837.48MB total

     flat  flat%  sum%        cum  cum%

 837.48MB  100%  100%  837.48MB  100%  main.main.func1

(3) go tool pprof http://localhost:6060/debug/pprof/block

(4) go tool pprof http://localhost:6060/debug/pprof/mutex

3.2.2.3 直接可视化查看(火焰图)

只需添加一个参数-http并指定端口,即可直接在web页面查看

go tool pprof -http=:8099 http://localhost:6060/debug/pprof/heap

或者通过pprof查看,效果是一样的

$ pprof -http=:8099 http://localhost:6060/debug/pprof/heap
  1. 火焰图
    它的最大优点是动态的。调用顺序由上到下(A -> B -> C -> D),每一块代表一个函数,越大代表占用 CPU 的时间更长。同时它也支持点击块深入进行分析!
  1. Top
  1. Graph

框越大,线越粗代表它占用的时间越大哦

  1. Peek
  1. Source



    通过 PProf 的可视化界面,我们能够更方便、更直观的看到 Go 应用程序的调用链、使用情况等,并且在 View 菜单栏中,还支持如上多种方式的切换

你想想,在烦恼不知道什么问题的时候,能用这些辅助工具来检测问题,是不是瞬间效率翻倍了呢 ?

总结

在本章节,粗略地介绍了 Go 的性能利器 PProf。在特定的场景中,PProf 给定位、剖析问题带了极大的帮助

参考链接:
https://blog.csdn.net/cscrazybing/article/details/78686941
http://www.brendangregg.com/flamegraphs.html

上一篇 下一篇

猜你喜欢

热点阅读