go 调试利器之pprof指标分析

文章目录

    • 概要
    • 一、指标类型
        • 1.1、堆栈指标
        • 1.2、CPU指标分析
        • 1.3、http-pprof
    • 二、go tool pprof
        • 2.1、可视化
        • 2.2、CPU火焰图

概要

Go语言原生支持对于程序运行时重要指标或特征进行分析。pprof是其中一种重要的工具,其不仅可以分析程序运行时的错误(内存泄漏、并发冲突、协程泄漏等),也可以对程序进行优化(比如定位cpu,内存异常逻辑)。由于Go程序运行时不对外暴漏相关指标,因此Go提供了runtime/pprofnet/http/pprof基础库来与外界交互,其中net/http/pprof是对runtime/pprof的进一步封装,让用户可以通过http获取相关指标。

一、指标类型

本章节我们结合源码来看看有哪些指标提供给我们。

1.1、堆栈指标

// profiles records all registered profiles.
var profiles struct {
	mu sync.Mutex
	m  map[string]*Profile
}
//	goroutine    - stack traces of all current goroutines
//	heap         - a sampling of memory allocations of live objects
//	allocs       - a sampling of all past memory allocations
//	threadcreate - stack traces that led to the creation of new OS threads
//	block        - stack traces that led to blocking on synchronization primitives
//	mutex        - stack traces of holders of contended mutexes
func lockProfiles() {
	profiles.mu.Lock()
	if profiles.m == nil {
		// Initial built-in profiles.
		profiles.m = map[string]*Profile{
			"goroutine":    goroutineProfile,//go协程堆栈分析
			"threadcreate": threadcreateProfile,//创建新系统级线程的堆栈跟踪
			"heap":         heapProfile,//活跃对象内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
			"allocs":       allocsProfile,//过去所有内存分配的抽样,heap的结果是包含它的
			"block":        blockProfile,//导致阻塞的同步原语堆栈追踪
			"mutex":        mutexProfile,//互斥锁分析,争用互斥锁持有者的堆栈跟踪
		}
	}
}

示例

	saveFile, err := os.OpenFile("./goroutine.out", os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		log.Println(err)
		return
	}
	err = pprof.Lookup("goroutine").WriteTo(saveFile, 0)
	if err != nil {
		log.Println(err)
	}

1.2、CPU指标分析

cpu指标分析并没有注册到全局变量到profiles.m中管理,而是需要手动开启,并在不需要采集时手动关闭。其以100hz的频率采集相关数据。

func StartCPUProfile(w io.Writer) error {
	//代码省略。。。
}
func StopCPUProfile() {
	//代码省略。。。
}

示例

	saveFile, err := os.OpenFile("./cpu.out", os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		log.Println(err)
		return
	}
	if err = pprof.StartCPUProfile(saveFile); err != nil {
		log.Println("could not start CPU profile: ", err)
		return
	}
	//after sometime call StopCPUProfile
	defer pprof.StopCPUProfile()

runtime/pprof一般适合只跑一次的程序,下面我们看看net/http/pprof如何使用的吧。

1.3、http-pprof

http模式是最常用的,前面说过,http就是对runtime/pprof的封装,其本质也是调的runtime/pprof的函数。
下面是http模式提供的http接口。

func init() {
	http.HandleFunc("/debug/pprof/", Index)//runtime/pprof 的 profiles.m 里注册的指标
	http.HandleFunc("/debug/pprof/cmdline", Cmdline)//仅打印程序启动时的参数 
	http.HandleFunc("/debug/pprof/profile", Profile)//runtime/pprof 的StartCPUProfile/StopCPUProfile
	http.HandleFunc("/debug/pprof/symbol", Symbol)
	http.HandleFunc("/debug/pprof/trace", Trace)//runtime/trace,进行事件追踪(协程的创建,开始,结束。网络IO事件。协程阻塞事件等),属于宏观视图,具体细节还要要看pprof
}

示例

package main

import (
	"log"
	"net/http"
	_ "net/http/pprof"
	"sync"
	"time"
)

func main() {
	go testHttpPprof()
	err := http.ListenAndServe("0.0.0.0:8888", nil)
	if err != nil {
		log.Fatal(err)
	}
}
func testHttpPprof() {
	i := 0
	for {
		go Add(i)
		time.Sleep(time.Second)
		i++
	}
}

var (
	sum  = 0
	data []int
	lock sync.Mutex
)

func Add(x int) {
	defer lock.Unlock()
	if x&1 == 0 {
		time.Sleep(time.Second)
	} else {
		time.Sleep(2 * time.Second)
	}
	lock.Lock()
	sum += x
	data = append(data, sum)
}

只需要导入net/http/pprof库,再起一个http服务,就可以通过http访问相关指标了。

http://127.0.0.1:8888/debug/pprof/ #查看可用指标接口
在这里插入图片描述
http://127.0.0.1:8888/debug/pprof/heap #查看内存堆栈分析
http://127.0.0.1:8888/debug/pprof/goroutine?debug=1 #查看所有协程堆栈信息
http://127.0.0.1:8888/debug/pprof/goroutine?seconds=30 #查看30s内所有协程堆栈信息
http://127.0.0.1:8888/debug/pprof/profile?seconds=30 #查看未来30s内的CPU数据分析
依次类推…

当携带参数debug时是返回当前堆栈数据,否则返回的是一个可下载的文件
获取到文件后,可以用go tool pprof xxx来分析文件。

二、go tool pprof

这里以内存指标分析为例,首先通过http://127.0.0.1:8888/debug/pprof/heap?seconds=30获取一个pprof文件。
go tool pprof -h 可以查看所有指令
go-pprof
常用的指令:

  • top -cum #根据cum从大到小排序,默认根据flat从大到小排序。在heap分析下cum是从当前函数开始累计内存占用。flat是当前函数分配的内存,其他分析(cpu,mutex等)为维度不同的含义。
  • tree #函数调用链
  • list xxx #列出某个函数的信息

另外 heap分析有四种不同类型的内存分析维度:alloc_objects、alloc_space、inuse_objects、inuse_space
alloc_objects和inuse_objects表示申请的对象和正在使用的对象;
alloc_space和inuse_space表示申请的内存和正在使用的内存;

默认是inuse_objects,切换很简单,只需输入 alloc_objects 就能切到alloc_objects维度。

2.1、可视化

pprof提供了强大的可视化功能,可以将内容转化成图片或html,只不过需要先安装graphviz

这样在命令行中输入web,png,gif等命令就可以输出相应可视化结果。
go-pprof-ui
如图,就会生成一张个png图片。

2.2、CPU火焰图

如同2.1节,获取cpu数据文件后,除了可以用go tool pprof生成png文件外,还可以生成火焰图,命令如下:

go tool pprof -http :8889 http://127.0.0.1:8888/debug/pprof/profile?seconds=90

稍等一会就可以通过8889端口访问火焰图了(通过VIEW菜单可以切换到不同可视化方式来查看)
go-cpu火焰图
go-cpu-可视化

  • 箭头越粗代表当前路径越消耗资源(内存,时间等);
  • 箭头为虚线表示两个节点之间的某些节点已被忽略,为间接调用;
  • 节点颜色红色表示cum累计值为正数,并且很大;绿色表示cum累计值为负数,并且很大;灰色表示cum累计值可以忽略不计。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29760.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

绕过激活锁 ,拯救一台旧手机iphone

一台旧的iphone忘了apple id账号和密码了,导致锁住了 某宝上解锁要花50, 不是舍不得花钱,作为一个搞技术的,实在觉得花钱有点丢人 经过一番探索 最终确定了有用的流程 并贴出来 亲测可用 最终实现了趟再床上就可以打卡 1、 刷机 …

【软件测试】性能测试服务端—排查指标问题(详细)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 软件性能测试的目…

node安装后的全局环境变量配置

安装node时,位置最好不要装在c盘,这里,我在D盘下创建了文件夹"node",安装地址选择在该文件夹下 一直next,直到安装结束,打开"node"文件夹,安装完后,里面的配置…

未来10年,网络安全人才就业的黄金期

随着大数据、物联网、人工智能等新技术的发展,信息技术与经济社会各领域的融合也更加深入。网络攻击行为日趋复杂、黑客攻击行为组织性更强、针对手机无线终端的网络攻击日趋严重,近几年有关网络攻击和数据泄露的新闻层出不穷。因此,随着国家…

Nodejs一、初识

零、文章目录 Nodejs一、初识 1、初识 Node.js (1)回顾与思考 浏览器中的 JavaScript 的组成部分 为什么 JavaScript 可以在浏览器中被执行 为什么 JavaScript 可以操作 DOM 和 BOM 浏览器中的 JavaScript 运行环境 JavaScript 能否做后端开发&#…

MySQL - 第0节 - MySQL在Centos 7环境安装

目录 1.安装前说明 2.MySQL在Centos 7环境安装 2.1.卸载不要的环境 2.2.配置mysql官方yum源 2.3.检查yum源能否正常工作 2.4.安装mysql 2.5.检查mysql是否安装成功 2.6.启动mysqld数据库服务端 2.7.三种登录方法 2.7.1.登陆方法一 2.7.2.登陆方法二 2.7.3.登陆方法…

Pandas+Pyecharts | 中国高校及专业数据分析可视化

文章目录 🏳️‍🌈 1. 导入模块🏳️‍🌈 2. Pandas数据处理2.1 读取数据 🏳️‍🌈 3. Pyecharts数据可视化3.1 全国高校分布地图3.2 全国高校分布城市地图3.3 本科/专科占比3.4 985/211/双一流高校数量占比…

【考研复习】李春葆新编C语言习题与解析(错误答案订正)持续更新

新编C语言习题与解析 做习题时发现有些错误答案,写篇博客进行改正记录。不对地方欢迎指正~ 第二章 C. 其中b的表达形式错误,若加上0x1e2b则正确。所以C错误。 D. e后为整数。指数命名规则:e前有数,后有整数。所以D错…

【CEEMDAN-CNN-LSTM】完备集合经验模态分解-卷积神经长短时记忆神经网络研究(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

getopt函数和getopt_long函数

这个函数有点像无限迷宫,正确的路和错误的路都有很多,我们只需要能够满足当前需求就可以了,完全没有必要去探索每一条路。虽然,我很久以前试图这样干过。过滤后的回忆,只剩感觉了,过滤的多了,感…

【简单便捷】解决Ubuntu内存不足问题:Ubuntu16.0.4 进行内存扩容

文章目录 电脑环境前言一、总述二、先在标题:虚拟机-->设置上进行扩容三、扩容之后 打开终端 执行 sudo apt install gparted四、执行 sudo gparted五、扩容成功六、重启测试 可以看到大概率成功了。 电脑环境 Windows 11 专业版系统 前言 在开发初期&#xf…

二叉树的相关操作

一.二叉树 本文的数据结构基于C语言练习。 C语言中的二叉树是一种数据结构,用于表示具有层次关系的数据集合。它由一个根节点开始,每个节点最多有两个子节点,分别称为左子节点和右子节点。 二叉树有许多相关性质,其中一些重要的包…

【CSS---定位基础篇】

CSS---定位基础篇 CSS-----基础定位:一 、 学习定位原因:(定位的作用)二 、定位组成:2.1 四种定位模式:(1)静态定位(了解):(2)相对定位…

ElasticSearch笔记02-ElasticSearch入门

ElasticSearch安装 下载软件 ElasticSearch的官网,视频教程里用的Version是7.8.0,所以,我们也是用7.8.0版本的ElasticSearch。 下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch,然后搜索…

lua的元表与元方法理解

元表 在 Lua 中,元表(metatable)是一种特殊的表,用于定义另一个表的行为。每个表都有一个关联的元表,通过元表可以重载表的各种操作,例如索引、新索引、相加等。在 Lua 中,元表的使用非常灵活&…

二、线性神经网络

文章目录 前言一、线性回归1. 线性回归的基本元素1.1 线性模型1.2 损失函数1.3 解析解1.4 梯度下降1.5 用模型进行预测 2. 正态分布与平方损失3. 从线性回归到深度网络 二、线性回归的代码实现1. 生成数据集2. 读取数据集2.1 手动实现读取数据集2.2 简洁实现读取数据集 3. 初始…

基于SpringBoot+Vue的自习室预订系统设计与实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

深度学习卷积神经网络CNN之ResNet模型网络详解说明(超详细理论篇)

1.ResNet背景 2. ResNet论文 3. ResNet模型结构 4. ResNet优缺点 一、ResNet背景 ResNet 在2015 年由微软研究院提出的一种深度卷积神经网络结构,在ILSVRC(ImageNet Large Scale Visual Recognition Challenge)中取得了冠军(分类…

OpenCV(图像处理)-基于Python-形态学处理-开运算、闭运算、顶帽、黑帽运算

1. 形态学2. 常用接口2.1 cvtColor()2.2 图像二值化threshod()自适应阈值二值化adaptiveThreshod() 2.3 腐蚀与膨胀erode()getStructuringElement()dilate() 2.4开、闭、梯度、顶帽、黑帽运算morphologyEx() 1. 形态学 OpenCV形态学是一种基于OpenCV库的数字图像处理技术&…

如何安装MySQL数据库

目录 什么是MySQL数据库 第一步 安装依赖环境 第二步 创建MySQL相关进程用户 第三步 导入MySQL相关包 第四步 解包到指定目录下 第五步 切换到MySQL目录下编译安装 第六步 编译 第七步 更改指定文件的所有者和所属组 第八步 进入指定配置文件清空内容 第九步 配置指定…