go 调试利器之pprof指标分析

这篇具有很好参考价值的文章主要介绍了go 调试利器之pprof指标分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概要

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/ #查看可用指标接口
go 调试利器之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指标分析
如图,就会生成一张个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 调试利器之pprof指标分析
go 调试利器之pprof指标分析文章来源地址https://www.toymoban.com/news/detail-489735.html

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

到了这里,关于go 调试利器之pprof指标分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • prometheus涉及pprof go信息泄露漏洞整改

    本文记录一下对系统渗透测试后反馈Prometheus涉及pprof go信息泄露,验证方法为http://ip:port/debug/pprof。为防止未经授权用户访问,现决定在Prometheus层面使用basic_auth加密整改。 软件 版本 Kylin V10 Docker 20.10.22 Prometheus 2.19.0 安装工具包并生成加密后密码 新建配置文件(暂时不使用

    2024年02月02日
    浏览(26)
  • Go语言远程调试

    我们远程(Linux服务器)有如下代码: main.go 文件的内容如下: 对 main.go 进行编译: 远程使用 dlv 启动程序: 在 windows 上进行远程连接: 在远程(Linux服务器)代码目录下启动 dlv: 然后在 vscode 中配置远程调试: 删除 \\\"remotePath\\\": \\\"${workspaceFolder}\\\", 这一行。 下面我们进行调试,在代

    2024年02月12日
    浏览(29)
  • Go性能调优及相关工具使用(四)——性能调优工具pprof的使用

    本堂课的知识要点有哪些? 1、性能发现工具pprof 2、性能调优案例 1、性能调优简介 性能调优原则: 要依靠数据不是猜测 要 定位最大瓶颈 而不是细枝末节 不要过早优化 不要过度优化 2、性能发现工具pprof 说明: 1、希望知道应用在什么地方耗费了多少CPU、Memory 2、pprof是用于

    2024年02月08日
    浏览(35)
  • Gin框架原生方式切割日志,Go语言原生日志切割

    目录 摘要 痛点 正文 1.分析 io.Writer 接口 2.实现 io.Writer 接口 3.将它作为原生输出 4.将它作为 Gin 框架的输出 自定义一个日志输出,将go语言和gin框架的日志自动按天拆分。本文通过实现io.Writer接口的方式,替换原生和gin框架的默认Writer,并植入了自定义的逻辑。该示例只讲述

    2024年02月09日
    浏览(34)
  • 【Golang星辰图】数据管理利器:Go编程语言中的数据库和搜索引擎综合指南

    Go编程语言是一种强大、类型安全且高效的编程语言,它在处理数据库和搜索引擎方面有着广泛的应用。本篇文章将详细介绍几个Go编程语言中常用的数据库和全文搜索引擎,包括Go-bleve、Go-pgx、Go-leveldb/leveldb、Go-xorm、Go-mysql-driver和Go-bbolt/bbolt。对于每个工具,我们将介绍其功

    2024年03月26日
    浏览(49)
  • IDEA Go语言开发环境无法debug调试

    使用idea 搭建go开发环境后如果debug调试可能会遇到错误: could not launch process: decoding dwarf section info at offset 0x0: too short。 有些回答go get -u github.com/derekparker/delve/cmd/dlv 。如果使用go mod方式开发的话这种方式是行不通的,最直接的方法是把dlv项目下载下来自己编译生成dlv.exe。 进

    2024年02月14日
    浏览(38)
  • 云原生时代崛起的编程语言Go基础实战

    @ 目录 概述 定义 使用场景 Go 安全 使用须知 搜索工具 Go基础命令 标准库 基础语法 Effective Go 概览 命名规范 注释 变量 常量(const) 控制结构 数据类型 迭代(range) 函数 指针 字符串和符文 结构体(struct) 方法 接口(interface) 泛型 错误(errors) 恐慌(pinic) 推迟(defer) 恢复(

    2024年02月01日
    浏览(48)
  • Go语言(Golang)安装下载配置及debug调试

    与Java类似,Go语言使用前也需要安装开发环境,并配置环境变量。下面以Windows平台为例,演示整体流程。 官方网站可能访问不到 https://golang.org/,可以访问国内镜像网站下载Go安装包: https://studygolang.com/dl https://mirrors.nju.edu.cn/ 因为Go语言一直的迭代,入门时尽量选择较新的版

    2024年02月04日
    浏览(48)
  • 静态分析C语言生成函数调用关系的利器——GCC

    在《静态分析C语言生成函数调用关系的利器——cally和egypt》中我们介绍了如何使用GCC生成RTL文件,然后再借助cally和egypt来分析出调用关系的方法。GCC自身有命令可以生成代码内部的调用关系,即-fcallgraph-info参数。 Makes the compiler output callgraph information for the program, on a per-ob

    2024年01月25日
    浏览(36)
  • 云原生时代崛起的编程语言Go并发编程实战

    @ 目录 概述 基础理论 并发原语 协程-Goroutine 通道-Channel 多路复用-Select 通道使用 超时-Timeout 非阻塞通道操作 关闭通道 通道迭代 定时器-TimerAndTicker 工作池-Worker Pools 等待组-WaitGroup 原子操作-Atomic 互斥锁-Mutex 读写互斥锁-RWMutex 有状态协程 单执行-Once 条件-Cond 上下文-Context 信

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包