目录

什么是 Profile?

两种收集方式

工具型应用

服务型应用

go tool ppof 获取和分析 profile 数据

终端

可视化


什么是 Profile?

在计算机性能调试领域里,profile 就是对应用的画像,这里画像就是应用使用 CPU 和内存等情况,也就是说应用使用了多少 CPU 资源、都是哪些部分在使用、每个函数使用的比例是多少、有哪些函数在等待 CPU 资源等等。知道了这些,我们就能对应用进行规划,也能快速定位性能瓶颈。

Golang 是一个对性能特别看重的语言,因此语言中自带了 profile 的库,这篇文章就要讲解怎么在 golang 中做 profile。

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

  • CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
  • Memory profile(Heap profile):报告程序的内存使用情况
  • Block profile:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
  • Goroutine profile:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的

两种收集方式

分析 profile 第一步就是怎么获取应用程序的运行情况数据。Golang 提供了 runtime/pprof 和 net/http/pprof 两个库,分别应用于两种不同的应用。

工具型应用

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

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

去除错误处理只需要三行内容,一般把它们写在 main.go 文件中,应用程序启动之后就开始执行:

f, err := os.Create(*cpuprofile)
...
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()

应用执行结束后,就会生成一个文件,保存了我们的 CPU profile 数据。

要获得内存的数据,直接使用 WriteHeapProfile 即可,不用 start 和 stop 这两个步骤:

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

服务型应用

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

在 import 里添加一行:

import _ "net/http/pprof"

在主函数中启动服务监听端口:

go func() {http.ListenAndServe(":6060", nil)
}()

访问 /debug/pprof 即可得到下面的内容:

/debug/pprof/profiles:
0   block
756 goroutine
16100   heap
0   mutex
94  threadcreatefull goroutine stack dump

go tool ppof 获取和分析 profile 数据

有了 profile 数据之后(不管是文件还是网络请求),下一步就是要对这些数据进行分析。我们可以使用 go tool pprof 命令行工具。

在后面我们会生成调用关系图和火焰图,需要安装 graphviz 软件包,在 ubuntu 系统可以使用下面的命令:

$ sudo apt-get install -y graphviz

注意获取的 profile 数据是动态的,要想获得有效的数据,请保证应用处于较大的负载(比如正在运行的服务,或者通过其他工具模拟访问压力)。否则如果应用处于空闲状态,得到的结果可能没有任何意义。

我们以 CPU profile 分析为例介绍两种分析方法。

终端

go tool pprof 最简单的使用方式为 go tool pprof [binary] [source]binary 是应用的二进制文件,用来解析各种符号;source 表示 profile 数据的来源,可以是本地文件,也可以是 http 地址。比如:

 ➜  go tool pprof ./hyperkube http://172.16.3.232:10251/debug/pprof/profile
Fetching profile from http://172.16.3.232:10251/debug/pprof/profile
Please wait... (30s)
Saved profile in /home/cizixs/pprof/pprof.hyperkube.172.16.3.232:10251.samples.cpu.002.pb.gz
Entering interactive mode (type "help" for commands)
(pprof) 

这个命令会进行 CPU profile 分析,等待一段时间(默认是 30s,如果在 url 最后加上 ?seconds=60 参数可以调整采集数据的时间为 60s)之后,我们就进入了一个交互式命令行,可以对解析的结果进行查看和导出。可以通过 help 来查看支持的命令有哪些。

一个有用的命令是 topN,它列出最耗时间的地方:

(pprof) top10
130ms of 360ms total (36.11%)
Showing top 10 nodes out of 180 (cum >= 10ms)flat  flat%   sum%        cum   cum%20ms  5.56%  5.56%      100ms 27.78%  encoding/json.(*decodeState).object20ms  5.56% 11.11%       20ms  5.56%  runtime.(*mspan).refillAllocCache20ms  5.56% 16.67%       20ms  5.56%  runtime.futex10ms  2.78% 19.44%       10ms  2.78%  encoding/json.(*decodeState).literalStore10ms  2.78% 22.22%       10ms  2.78%  encoding/json.(*decodeState).scanWhile10ms  2.78% 25.00%       40ms 11.11%  encoding/json.checkValid10ms  2.78% 27.78%       10ms  2.78%  encoding/json.simpleLetterEqualFold10ms  2.78% 30.56%       10ms  2.78%  encoding/json.stateBeginValue10ms  2.78% 33.33%       10ms  2.78%  encoding/json.stateEndValue10ms  2.78% 36.11%       10ms  2.78%  encoding/json.stateInString

每一行表示一个函数的信息。前两列表示函数在 CPU 上运行的时间以及百分比;第三列是当前所有函数累加使用 CPU 的比例;第四列和第五列代表这个函数以及子函数运行所占用的时间和比例(也被称为累加值 cumulative),应该大于等于前两列的值;最后一列就是函数的名字。如果应用程序有性能问题,上面这些信息应该能告诉我们时间都花费在哪些函数的执行上了。

pprof 不仅能打印出最耗时的地方(top),还能列出函数代码以及对应的取样数据、汇编代码以及对应的取样数据。list 命令后面跟着一个正则表达式,就能查看匹配函数的代码以及每行代码的耗时:

 (pprof) list podFitsOnNode
Total: 120ms
ROUTINE ======================== k8s.io/kubernetes/plugin/pkg/scheduler.podFitsOnNode in /home/cizixs/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/plugin/pkg/scheduler/generic_scheduler.go0       20ms (flat, cum) 16.67% of Total.          .    230:.          .    231:// Checks whether node with a given name and NodeInfo satisfies all predicateFuncs..          .    232:func podFitsOnNode(pod *api.Pod, meta interface{}, info *schedulercache.NodeInfo, predicateFuncs map[string]algorithm.FitPredicate) (bool, []algorithm.PredicateFailureReason, error) {.          .    233:   var failedPredicates []algorithm.PredicateFailureReason.          .    234: for _, predicate := range predicateFuncs {.       20ms    235:     fit, reasons, err := predicate(pod, meta, info).          .    236:        if err != nil {.          .    237:            err := fmt.Errorf("SchedulerPredicates failed due to %v, which is unexpected.", err).          .    238:         return false, []algorithm.PredicateFailureReason{}, err.          .    239:     }.          .    240:       if !fit {

如果想要了解对应的汇编代码,可以使用 disasm <regex> 命令。

可视化

pprof 能以各种样式输出数据,比如 svg、gv、callgrind、png、gif 等等。其中一个非常便利的方法是在交互式终端中输入 web 命令,就能自动生成一个 svg 文件,并跳转到浏览器打开,生成了一个函数调用图:

这个调用图包含了更多的信息,而且可视化的图像能让我们更清楚地理解整个应用程序的全貌。图中每个方框对应一个函数,方框越大代表执行的时间越久(包括它调用的子函数执行时间,但并不是正比的关系);方框之间的箭头代表着调用关系,箭头上的数字代表被调用函数的执行时间。

因为原图比较大,这里只截取了其中一部分,但是能明显看到 encoding/json.(*decodeState).object 是这里耗时比较多的地方,而且能看到它调用了哪些函数。这些信息对于定位和调优性能是非常有帮助的。如果想进一步在浏览器中查看源代码和汇编代码,可以使用 weblist 命令,和 list、disadm 的用法相同,它能够同时显示源代码和汇编代码

此外还可以输入 pdf 命令生成一个 pdf 文件。更详细的 pprof 使用方法可以参考 pprof --help 或者 pprof 文档。

另一个可视化的方法是直接启动一个 http 服务:

go tool pprof -http="10.224.27.152:8081" ./hyperkube http://172.16.3.232:10251/debug/pprof/profile

在浏览器上访问 10.224.27.152:8081 即可看到各种界面。

注:本文大量使用了 使用 pprof 和火焰图调试 golang 应用 的内容,并结合了笔者平时的实践。

Golang pprof 使用相关推荐

  1. 白话 Golang pprof

    文章目录 0.前言 1.什么是 pprof 2.pprof 的作用是什么 3.pprof 的使用模式 4.安装 Graphviz 4.应用程序性能分析 4.1 CPU 性能分析 4.2 内存性能分析 ...

  2. golang pprof

    这里填写标题 1. golang pprof 1.1. pprof 实例 2. go tool 2.1. `--inuse/alloc_space` `--inuse/alloc_objects` 区 ...

  3. 使用golang pprof进行性能分析

    golang pprof,说实话自己还一次都没有实际操作过. 最近这几天的需求恰好需要分析下一个看似很简单的服务,内存配置上限是900m,最终在大量并发的时候出现oom的情况. 代码准备 首先代码需要 ...

  4. Golang pprof简介

    目录 概要 pprof的作用 使用方式 交互式常用命令 以profile为例,其余的指标也是用一样的命令 Top N List func Traces web func Base Debug=[num ...

  5. golang pprof工具

    pprof工具 pprof是什么 pprof是分析和显示性能相关数据的工具 pprof读取profile.proto格式的分析抽样集合数据,同时创建报告来展现和帮助分析数据,它能创建包括文本和图型报告 ...

  6. Golang pprof 性能分析与火焰图

    文章目录 1. 安装graphviz 1.1 下载 graphviz (windows 环境) 1.2 测试graphviz是否安装成功 2. 使用pprof 2.1 修改代码 2.2 火焰图生成 3 ...

  7. 一看就懂系列之Golang的pprof

    前言 这是一篇给网友的文章,正好最近在研究分析golang的性能,我觉得是时候来一个了断了. 正文 1.一句话简介 Golang自带的一款开箱即用的性能监控和分析工具. (全篇看的过程中没必要特意记忆 ...

  8. golang 内存分析/动态追踪

    https://my.oschina.net/ytqvip/blog/1920459 golang pprof 当你的golang程序在运行过程中消耗了超出你理解的内存时,你就需要搞明白,到底是 程序 ...

  9. golang profiling

    这里写目录标题 1. Golang Profiling 1.1. runtime/pprof 包的使用 1.2. net/http/pprof 包的使用 2. 创建火焰图 2.1. 安装 go-tor ...

最新文章

  1. 2400门课:MIT 开放迄今最全 计算机+电气工程课程
  2. 什么是Attention机制以及Pytorch如何使用
  3. php7 windows2008,【笔记】Windows Server2008 R2 安装 PHP7 缺少 API-ms-win-crt-runtime-l1-1-0.dll 解决方案...
  4. 服务网格架构激活了容器网络管理—来自于服务网格创建者们的见解与展望
  5. Zabbix 监控TCP的SYN,establised
  6. 内存模型是怎么解决缓存一致性的
  7. 光端机使用过程中碰到的九大问题
  8. truffle serve 发生异常解决办法
  9. highcharts.js两种数据绑定方式和异步加载数据的使用
  10. 数组02 - 零基础入门学习C语言24
  11. 实现二叉树的基本操作(Java版)
  12. Python 实现单例模式的一些思考
  13. 可用性SLA还不懂?看完这个故事就懂了........ | 凌云时刻
  14. Html5用户注册页面
  15. 进程调度:时间片轮转调度算法
  16. 苹果市值超过微软 重新成为全球市值最高上市公司
  17. 输入法兼容 android,搜狗输入法5.1版发布 兼容Android 4.4
  18. 项目管理中用什么工具可以增强团队协作?
  19. IPC技术与评分卡技术区别
  20. Python处理Excel求取某列固定间隔数的平均值

热门文章

  1. 输入法字母变形问题解决
  2. 计算机系女学霸,稳居专业第一!计算机女学霸:两获国家奖学金,保研985继续深造...
  3. c语言编程表示%d,C语言编程中a=%d是什么意思啊
  4. java 注解值_java 注解默认值操作
  5. 在photoshop中如何设置一张a4纸上打印多个照片,如小二寸图片排版
  6. 首字母为A的4字成语
  7. 梦幻模拟战手游最新服务器,《梦幻模拟战手游》新手开服必读,五分钟教你成为高端玩家...
  8. win10wifi开关自动弹回_win10打不开wlan,win10wlan开关自动弹回
  9. 短视频系统源码,检测在手机上的触摸按下、拖拽、抬手
  10. 吉利花90亿美元成奔驰母公司最大股东,背后打的什么算盘?