[分享] Golang 性能分析 - Praefect

Golang 性能分析

pprofgo自身提供的用于可视化和分析性能数据的工具。在遇到性能问题时,可以使用它进行分析。比如:

  • 监控发现进程的CPU 使用率过高;
  • 内存占用不断增大,疑似内存泄露;
  • 临时内存大量申请后长时间内不释放;
  • Goroutine 数量暴涨,并且长时间持续保持;

pprof支持的模式:

  • 报告生成
  • 交互式终端
  • Web UI

pprof可以做什么:

  • CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置
  • Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
  • Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置
  • Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况

极狐GitLab的Praefect组件使用了Go语言编写,因此在遇到性能问题时,可以使用此工具进行分析。

1. 下载profiles

首先,做一个ssh端口转发,将profile直接下载到你的本地工作站,比如我们将praefect端口9652,转发到本地工作站的6060端口(6060是pprof的常用端口)

# praefect
ssh -N -L 6060:localhost:9652 gitlab-06
# 获取30秒的CPU profiling
curl -o cpu.bin http://localhost:6060/debug/pprof/profile

# 获取5秒的执行跟踪(有一定性能影响)
curl -o trace.bin http://localhost:6060/debug/pprof/trace?seconds=5

# 获取内存使用的profile
curl -o heap.bin http://localhost:6060/debug/pprof/heap

# 获取正在运行的goroutines列表
curl -o goroutines.txt http://localhost:6060/debug/pprof/goroutine?debug=2

# 获取被blocking的goroutine列表
curl -o goroutines-blocking.txt http://localhost:6060/debug/pprof/block

2. 提交profile

将profile文件提交给极狐GitLab技术支持团队。

3. 分析profile

需安装go SDK

yum -y install golang

3.1 查找cpu使用

  • 运行 go tool pprof cpu.bin 进入交互模式

    • 使用 top 30 显示消费cpu最多的30个方法
    • 大多数情况下,可以根据cpu累积消耗进行排序: top 30 -cum
  • 使用非交互模式:

    go tool pprof -top 30 -cum cpu.bin
    

    其中flat代表的是该函数自身代码的执行时长,而cum代表的是该函数自身代码+所有调用的函数的执行时长.

  • 选择其中一个方法,并查看其每一行代码的cpu消耗:

    go tool pprof -source_path </path/to/go_src> -list <methodname_regexp> cpu.bin
    
  • 网页可视化显示:

    go tool pprof -http localhost:8080 cpu.bin
    

3.1 查看内存使用

  • 运行 go tool pprof heap.bin 进入交互模式

    • 使用 top 30 显示消费内存最多的30个方法
    • 大多数情况下,可以根据内存累积消耗进行排序: top 30 -cum
  • 使用非交互模式

    go tool pprof -top 30 -cum heap.bin
    
  • 选择其中一个方法,并查看其每一行代码的内存消耗:

    go tool pprof -source_path </path/to/go_src> -list <methodname_regexp> heap.bin
    
  • 网页可视化显示

    需要安装graphviz:

    yum -y install graphviz
    

    使用本机8080端口:

    go tool pprof -http localhost:8080 heap.bin
    

    图形:

    框越大,线越粗,代表占用的资源越多。

分析go应用程序的常驻内存占用情况:

分析go应用程序的内存临时分配情况:

参考资料

  1. Gitaly Profiling