【go语言开发】性能分析工具pprof使用

news2024/10/7 16:19:58

本文主要介绍如何在项目中使用pprof工具。首先简要介绍pprof工具的作用;然后介绍pprof的应用场景,主要分为工具型应用和服务型应用。最后数据分析项目,先采集项目信息,再可视化查看

文章目录

  • 前言
  • 应用场景
    • 工具型应用
    • 服务型应用
  • 数据分析
    • 命令行查看
    • 采集数据
    • 查看数据
      • top
      • Graph
      • Flame Graph
      • Source

欢迎大家访问个人博客网址:https://www.maogeshuo.com,博主努力更新中…

前言

pprof是Go语言的一个性能分析库,它的名字源于**“Profile”(简称"prof")**一词。该工具最早由Google开发并用于Go语言的性能分析,它可以帮助开发者找出程序中的性能瓶颈。pprof提供了CPU分析、内存分析、阻塞分析等多种性能分析功能。

  1. CPU分析
  • pprof可以通过采样应用程序的运行状态来分析CPU的使用情况,找出哪些函数占用了大量的CPU时间。
  • 提供CPU使用率最高的函数列表和调用关系,帮助定位程序的CPU性能瓶颈。
  1. 内存分析
  • 支持对应用程序的内存分配和使用情况进行分析,帮助开发人员发现内存泄漏、高内存消耗的函数等问题。
  • 提供内存使用最多的函数列表和调用关系,帮助优化内存管理和减少不必要的内存分配。
  1. 阻塞分析
  • pprof可以分析应用程序中的阻塞情况,识别并发执行过程中可能存在的阻塞问题。
  • 提供阻塞最严重的代码段和调用关系,帮助优化并发执行的性能和减少阻塞时间。
  1. goroutine分析
  • 支持对应用程序中goroutine的跟踪和分析,帮助理解并发执行情况。
  • 提供goroutine的数量、状态和调用关系等信息,帮助优化并发编程和避免goroutine泄漏。
  1. 堆分析
  • pprof可以生成堆内存分配和释放的时间序列图,帮助开发人员了解程序在运行过程中的内存分配情况。
  • 提供堆内存使用的趋势和波动情况,帮助优化内存管理和减少内存占用。

除了这些功能外,pprof还提供了对运行时调用图的可视化展示。pprof可以很容易地集成到任何Go程序中,只需在程序中导入net/http/pprof包,并启动一个HTTP服务器,就可以通过Web界面查看性能数据。

应用场景

pprof工具的应用场景主要分为两种:

  • 服务型应用:web服务性能分析
  • 工具型应用:输入命令行应用等

工具型应用

如果你想在不使用HTTP服务的情况下对应用程序进行性能分析,可以直接使用 runtime/pprof 包中提供的函数来生成性能分析数据。

package main

import (
	"log"
	"os"
	"runtime"
	"runtime/pprof"
	"time"
)

func main() {
	Analysis()
}

func Analysis() {
	// 创建 CPU 分析文件
	cpuProfile, err := os.Create("./profile/cpu.prof")
	if err != nil {
		log.Fatal(err)
	}
	defer cpuProfile.Close()

	// 开始 CPU 分析
	if err := pprof.StartCPUProfile(cpuProfile); err != nil {
		log.Fatal(err)
	}
	defer pprof.StopCPUProfile()

	// 模拟一些 CPU 密集型工作
	for i := 0; i < 1000000; i++ {
		_ = i * i
	}

	// 创建内存分析文件
	memProfile, err := os.Create("./profile/mem.prof")
	if err != nil {
		log.Fatal(err)
	}
	defer memProfile.Close()

	// 强制进行垃圾回收,以便获取准确的内存分析数据
	runtime.GC()

	// 开始内存分析
	if err := pprof.WriteHeapProfile(memProfile); err != nil {
		log.Fatal(err)
	}

	// 模拟一些内存使用
	data := make([]byte, 1024*1024)
	_ = data

	time.Sleep(time.Second) // 等待一段时间以便生成分析数据

	log.Println("完成性能分析")
}

服务型应用

我们这里使用gin框架,结合https://github.com/gin-contrib/pprof

package main

import (
	webpprof "github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"runtime"
	"runtime/pprof"

	"time"
)

const Port = ":10000"

func main() {
	WebAnalysis()
}

func WebAnalysis() {
	g := gin.Default()
	g.GET("/test", func(c *gin.Context) {
		c.JSON(http.StatusOK, "测试成功")
	})
	webpprof.Register(g) // 注入HandlerFuncs
	g.Run(Port)

}

启动后日志打印如下:
在这里插入图片描述

查看github.com/gin-contrib/pprof代码,发现gin.Enginenet/http/pprof的函数封装成标准的HandlerFuncs,也就是将func(w http.ResponseWriter, r *http.Request)格式函数转换为gin.HandlerFunc

package pprof

import (
	"net/http/pprof"

	"github.com/gin-gonic/gin"
)

const (
	// DefaultPrefix url prefix of pprof
	DefaultPrefix = "/debug/pprof"
)

func getPrefix(prefixOptions ...string) string {
	prefix := DefaultPrefix
	if len(prefixOptions) > 0 {
		prefix = prefixOptions[0]
	}
	return prefix
}

// Register the standard HandlerFuncs from the net/http/pprof package with
// the provided gin.Engine. prefixOptions is a optional. If not prefixOptions,
// the default path prefix is used, otherwise first prefixOptions will be path prefix.
func Register(r *gin.Engine, prefixOptions ...string) {
	RouteRegister(&(r.RouterGroup), prefixOptions...)
}

// RouteRegister the standard HandlerFuncs from the net/http/pprof package with
// the provided gin.GrouterGroup. prefixOptions is a optional. If not prefixOptions,
// the default path prefix is used, otherwise first prefixOptions will be path prefix.
func RouteRegister(rg *gin.RouterGroup, prefixOptions ...string) {
	prefix := getPrefix(prefixOptions...)

	prefixRouter := rg.Group(prefix)
	{
		prefixRouter.GET("/", gin.WrapF(pprof.Index))
		prefixRouter.GET("/cmdline", gin.WrapF(pprof.Cmdline))
		prefixRouter.GET("/profile", gin.WrapF(pprof.Profile))
		prefixRouter.POST("/symbol", gin.WrapF(pprof.Symbol))
		prefixRouter.GET("/symbol", gin.WrapF(pprof.Symbol))
		prefixRouter.GET("/trace", gin.WrapF(pprof.Trace))
		prefixRouter.GET("/allocs", gin.WrapH(pprof.Handler("allocs")))
		prefixRouter.GET("/block", gin.WrapH(pprof.Handler("block")))
		prefixRouter.GET("/goroutine", gin.WrapH(pprof.Handler("goroutine")))
		prefixRouter.GET("/heap", gin.WrapH(pprof.Handler("heap")))
		prefixRouter.GET("/mutex", gin.WrapH(pprof.Handler("mutex")))
		prefixRouter.GET("/threadcreate", gin.WrapH(pprof.Handler("threadcreate")))
	}
}

实际上net/http/pprof库中已初始化的函数有Index等,并在此基础上再wrap了heap、mutex等


// Package pprof serves via its HTTP server runtime profiling data
// in the format expected by the pprof visualization tool.
//
// The package is typically only imported for the side effect of
// registering its HTTP handlers.
// The handled paths all begin with /debug/pprof/.
//
// To use pprof, link this package into your program:
//
//	import _ "net/http/pprof"
//
// If your application is not already running an http server, you
// need to start one. Add "net/http" and "log" to your imports and
// the following code to your main function:
//
//	go func() {
//		log.Println(http.ListenAndServe("localhost:6060", nil))
//	}()
//
// By default, all the profiles listed in [runtime/pprof.Profile] are
// available (via [Handler]), in addition to the [Cmdline], [Profile], [Symbol],
// and [Trace] profiles defined in this package.
// If you are not using DefaultServeMux, you will have to register handlers
// with the mux you are using.
//
// # Usage examples
//
// Use the pprof tool to look at the heap profile:
//
//	go tool pprof http://localhost:6060/debug/pprof/heap
//
// Or to look at a 30-second CPU profile:
//
//	go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
//
// Or to look at the goroutine blocking profile, after calling
// runtime.SetBlockProfileRate in your program:
//
//	go tool pprof http://localhost:6060/debug/pprof/block
//
// Or to look at the holders of contended mutexes, after calling
// runtime.SetMutexProfileFraction in your program:
//
//	go tool pprof http://localhost:6060/debug/pprof/mutex
//
// The package also exports a handler that serves execution trace data
// for the "go tool trace" command. To collect a 5-second execution trace:
//
//	curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
//	go tool trace trace.out
//
// To view all available profiles, open http://localhost:6060/debug/pprof/
// in your browser.
//
// For a study of the facility in action, visit
//
//	https://blog.golang.org/2011/06/profiling-go-programs.html
package pprof

import (
	"bufio"
	"bytes"
	"context"
	"fmt"
	"html"
	"internal/profile"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"runtime/pprof"
	"runtime/trace"
	"sort"
	"strconv"
	"strings"
	"time"
)
func init() {
	http.HandleFunc("/debug/pprof/", Index)
	http.HandleFunc("/debug/pprof/cmdline", Cmdline)
	http.HandleFunc("/debug/pprof/profile", Profile)
	http.HandleFunc("/debug/pprof/symbol", Symbol)
	http.HandleFunc("/debug/pprof/trace", Trace)
}

浏览器输入http://localhost:10000/debug/pprof/
pprof能分析9项信息

在这里插入图片描述

数据分析

命令行查看

go tool pprof
usage:

Produce output in the specified format.

   pprof <format> [options] [binary] <source> ...

Omit the format to get an interactive shell whose commands can be used
to generate various views of a profile

   pprof [options] [binary] <source> ...

Omit the format and provide the "-http" flag to get an interactive web
interface at the specified host:port that can be used to navigate through
various views of a profile.

   pprof -http [host]:[port] [options] [binary] <source> ...

Details:
  Output formats (select at most one):
    -callgrind       Outputs a graph in callgrind format
    -comments        Output all profile comments
    -disasm          Output assembly listings annotated with samples
    -dot             Outputs a graph in DOT format
    -eog             Visualize graph through eog
    -evince          Visualize graph through evince
    -gif             Outputs a graph image in GIF format
    -gv              Visualize graph through gv
    -kcachegrind     Visualize report in KCachegrind
    -list            Output annotated source for functions matching regexp
    -pdf             Outputs a graph in PDF format
    -peek            Output callers/callees of functions matching regexp
    -png             Outputs a graph image in PNG format
    -proto           Outputs the profile in compressed protobuf format
    -ps              Outputs a graph in PS format
    -raw             Outputs a text representation of the raw profile
    -svg             Outputs a graph in SVG format
    -tags            Outputs all tags in the profile
    -text            Outputs top entries in text form
    -top             Outputs top entries in text form
    -topproto        Outputs top entries in compressed protobuf format
    -traces          Outputs all profile samples in text form
    -tree            Outputs a text rendering of call graph
    -web             Visualize graph through web browser
    -weblist         Display annotated source in a web browser

  Options:
    -call_tree       Create a context-sensitive call tree
    -compact_labels  Show minimal headers
    -divide_by       Ratio to divide all samples before visualization
    -drop_negative   Ignore negative differences
    -edgefraction    Hide edges below <f>*total
    -focus           Restricts to samples going through a node matching regexp
    -hide            Skips nodes matching regexp
    -ignore          Skips paths going through any nodes matching regexp
    -intel_syntax    Show assembly in Intel syntax
    -mean            Average sample value over first value (count)
    -nodecount       Max number of nodes to show
    -nodefraction    Hide nodes below <f>*total
    -noinlines       Ignore inlines.
    -normalize       Scales profile based on the base profile.
    -output          Output filename for file-based outputs
    -prune_from      Drops any functions below the matched frame.
    -relative_percentages Show percentages relative to focused subgraph
    -sample_index    Sample value to report (0-based index or name)
    -show            Only show nodes matching regexp
    -show_from       Drops functions above the highest matched frame.
    -source_path     Search path for source files
    -tagfocus        Restricts to samples with tags in range or matched by regexp
    -taghide         Skip tags matching this regexp
    -tagignore       Discard samples with tags in range or matched by regexp
    -tagleaf         Adds pseudo stack frames for labels key/value pairs at the callstack leaf.
    -tagroot         Adds pseudo stack frames for labels key/value pairs at the callstack root.
    -tagshow         Only consider tags matching this regexp
    -trim            Honor nodefraction/edgefraction/nodecount defaults
    -trim_path       Path to trim from source paths before search
    -unit            Measurement units to display

  Option groups (only set one per group):
    granularity
      -functions       Aggregate at the function level.
      -filefunctions   Aggregate at the function level.
      -files           Aggregate at the file level.
      -lines           Aggregate at the source code line level.
      -addresses       Aggregate at the address level.
    sort
      -cum             Sort entries based on cumulative weight
      -flat            Sort entries based on own weight

  Source options:
    -seconds              Duration for time-based profile collection
    -timeout              Timeout in seconds for profile collection
    -buildid              Override build id for main binary
    -add_comment          Free-form annotation to add to the profile
                          Displayed on some reports or with pprof -comments
    -diff_base source     Source of base profile for comparison
    -base source          Source of base profile for profile subtraction
    profile.pb.gz         Profile in compressed protobuf format
    legacy_profile        Profile in legacy pprof format
    http://host/profile   URL for profile handler to retrieve
    -symbolize=           Controls source of symbol information
      none                  Do not attempt symbolization
      local                 Examine only local binaries
      fastlocal             Only get function names from local binaries
      remote                Do not examine local binaries
      force                 Force re-symbolization
    Binary                  Local path or build id of binary for symbolization
    -tls_cert             TLS client certificate file for fetching profile and symbols
    -tls_key              TLS private key file for fetching profile and symbols
    -tls_ca               TLS CA certs file for fetching profile and symbols

  Misc options:
   -http              Provide web interface at host:port.
                      Host is optional and 'localhost' by default.
                      Port is optional and a randomly available port by default.
   -no_browser        Skip opening a browser for the interactive web UI.
   -tools             Search path for object tools

  Legacy convenience options:
   -inuse_space           Same as -sample_index=inuse_space
   -inuse_objects         Same as -sample_index=inuse_objects
   -alloc_space           Same as -sample_index=alloc_space
   -alloc_objects         Same as -sample_index=alloc_objects
   -total_delay           Same as -sample_index=delay
   -contentions           Same as -sample_index=contentions
   -mean_delay            Same as -mean -sample_index=delay

  Environment Variables:
   PPROF_TMPDIR       Location for saved profiles (default $HOME/pprof)
   PPROF_TOOLS        Search path for object-level tools
   PPROF_BINARY_PATH  Search path for local binary files
                      default: $HOME/pprof/binaries
                      searches $buildid/$name, $buildid/*, $path/$buildid,
                      ${buildid:0:2}/${buildid:2}.debug, $name, $path
   * On Windows, %USERPROFILE% is used instead of $HOME
no profile source specified

采集数据

可以将每项数据统一采集下来,再具体分析

go tool pprof http://localhost:10000/debug/pprof/allocs
go tool pprof http://localhost:10000/debug/pprof/block
go tool pprof http://localhost:10000/debug/pprof/cmdline
go tool pprof http://localhost:10000/debug/pprof/heap
go tool pprof http://localhost:10000/debug/pprof/mutex
go tool pprof http://localhost:10000/debug/pprof/profile
go tool pprof http://localhost:10000/debug/pprof/threadcreate
go tool pprof http://localhost:10000/debug/pprof/trace

终端中运行以下命令,性能分析allocs数据:
在这里插入图片描述
在这里插入图片描述

在进入 pprof 命令行界面后,你可以输入不同的命令来查看不同类型的分析数据,比如 top 查看 CPU 使用最多的函数,list 查看某个函数的详细信息,web 可以在浏览器中打开交互式图形界面等。

查看数据

查看数据,可以选择web形式,可视化效果直观,打开收集好的pb.gz文件
UI显示依赖graphviz库 ,mac安装使用命令为:brew install graphviz

go tool pprof -http:127.0.0.1:port pb.gz路径 //参考截图使用

在这里插入图片描述
浏览器输入http://127.0.0.1:8082/ui/,UI上查看各项信息
在这里插入图片描述

top

查看CPU/内存占有率最高的接口
在这里插入图片描述

Graph

在这里插入图片描述

Flame Graph

在这里插入图片描述

Source

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

22 OpenCV 直方图计算

文章目录 直方图概念split 通道分离函数calcHist 计算直方图normalize 归一化函数示例 直方图概念 上述直方图概念是基于图像像素值&#xff0c;其实对图像梯度、每个像素的角度、等一切图像的属性值&#xff0c;我们都可以建立直方图。这个才是直方图的概念真正意义&#xff0…

R语言:microeco:一个用于微生物群落生态学数据挖掘的R包,第六:trans_nullmodel class

近几十年来&#xff0c;系统发育分析和零模型的整合通过增加系统发育维度&#xff0c;更有力地促进了生态位和中性影响对群落聚集的推断。trans_nullmodel类提供了一个封装&#xff0c;包括系统发育信号、beta平均成对系统发育距离(betaMPD)、beta平均最近分类单元距离(betaMNT…

时间序列预测的零样本学习是未来还是炒作:TimeGPT和TiDE的综合比较

最近时间序列预测预测领域的最新进展受到了各个领域&#xff08;包括文本、图像和语音&#xff09;成功开发基础模型的影响&#xff0c;例如文本&#xff08;如ChatGPT&#xff09;、文本到图像&#xff08;如Midjourney&#xff09;和文本到语音&#xff08;如Eleven Labs&…

【GPT-SOVITS-06】特征工程-HuBert原理

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…

从0开始写一个问卷调查APP的第11天

1.今日任务 分析:上次我们实现了从数据库中成功的查找到对应问卷的问题并在前端展示出来&#xff0c;那么今天我们增加难度。在数据库中插入多项选择问题&#xff0c;在接口中查找到并在前端显示出来。 2.实现 2.1数据库中插入测试数据 我们先查看一下表的结构 2.2接口实现…

软件架构设计 C/S与B/S架构的区别

一、什么是C/S架构&#xff1f; C/S是Client/Server的缩写。服务器通常采用高性能的PC、工作站或小型机&#xff0c;并采用大型数据库系统&#xff0c;如Oracle或SQLServer。 C/S架构软件有一个特点&#xff0c;就是如果用户要使用的话&#xff0c;需要下载一个客户端&#x…

nodejs部署

字符集转换&#xff1a; mysql报错&#xff1a;Incorrect string value: \xF0\x9F... for column XXX at row 1_incorrect string value: \\xf0\\x9f\\x94\\xa5\\xe8-CSDN博客 查看nginx是否启动 ps -ef|grep nginx 检查nginx是否配置正确 nginx -t 防火墙开启端口 启动并…

CCDP.01.使用NotePad++辅助部署OpenStack的说明

前言 对于象OpenStack&#xff08;OS&#xff09;这样的复杂分布式系统&#xff08;云计算平台&#xff09;&#xff0c;一次部署通过是需要相当的Linux基础、网络基础、分布式系统基础、云计算基础的。这里类比在开发大型复杂系统常常采用的“防御式编程”方法论&#xff0c;探…

Vue中使用Lodash

Vue中使用Lodash 前言安装Lodash引用方法vue中使用1、cloneDeep 深拷贝2、uniq 数组去重3、uniqWith 数组对象去重 isEqual 深度比对4、intersection 提取数组相同元素5、chunk 数组切分6、compact去除假值7、reject:根据条件删除指定的值8、find:查找结果的第一个值9、filter:…

Machine Learning ---- Multiple linear regression equation

一、Multiple linear regression: In the study of real-world problems, the changes in the dependent variable are often influenced by several important factors. In this case, it is necessary to use two or more influencing factors as independent variables to e…

如何用Selenium通过Xpath,精准定位到“多个相同属性值以及多个相同元素”中的目标属性值

前言 本文是该专栏的第21篇,后面会持续分享python爬虫干货知识,记得关注。 相信很多同学,都有使用selenium来写爬虫项目或者自动化页面操作项目。同样,也相信很多同学在使用selenium来定位目标元素的时候,或多或少遇见到这样的情况,就是用Xpath定位目标元素的时候,页面…

AI系统性学习01- Prompt Engineering

文章目录 面向开发者的Prompt Engineering一、简介二、Prompt设计原则1 环境配置2.两个基本原则2.1 原则1&#xff1a;编写清晰、具体的指令2.1.1 策略一&#xff1a;分割2.1.2 策略2&#xff1a;结构化输出2.1.3 策略3&#xff1a;模型检测2.1.4 策略4&#xff1a;提供示例 2.…

Godot 学习笔记(1):环境配置

文章目录 前言Godot 环境配置相关链接最简单的按钮项目Sence打包最简单的按钮事件 总结 前言 我从小就有个梦想&#xff0c;我想做游戏。虽然我大学的时候选择了计算机&#xff0c;工作也是计算机&#xff0c;但是我一直没有时间去学游戏引擎。原因有二&#xff1a;第一&#…

学习数据结构和算法的第16天

单链表的实现 链表的基本结构 #pragma once #include<stdio.h> #include<stlib.h> typedf int SLTDataType; typedy struct SListNode {SLTDataType data;struct SListNode*next; }SLTNode;void Slisprint(SLTNode*phead); void SListPushBack(SLTNode**pphead,S…

常用芯片学习——DS3231M芯片

DS3231M RTC实时时钟 芯片介绍 DS3231M是一款低成本、极其精确的 I2C 实时时钟 &#xff08;RTC&#xff09;。该设备集成了电池输入&#xff0c;并在设备主电源中断时保持准确的计时。微型电子机械系统 &#xff08;MEMS&#xff09; 谐振器的集成提高了器件的长期精度&…

【记录搭建elk 如何在linux共享文件】

『如何在linux共享文件 &#xff0c;搭建elk直接看第二部分』 新增用户a b c adduser a adduser b adduser c新增用户组 A groupadd developteam将用户a b c 加入 组 usermod -a -G developteam hadoop usermod -a -G developteam hbase usermod -a -G developteam hive设置um…

Flutter 核心原理 - UI 框架(UI Framework)

Flutter 既能保证很高的开发效率&#xff0c;又能获得很好的性能。 这两年 Flutter 技术热度持续提高&#xff0c;整个 Flutter 生态和社区也发生了翻天覆地的变化。目前Flutter 稳定版发布到了3.0&#xff0c;现在已经支持移动端、Web端和PC端&#xff0c;通过Flutter 开发的…

【计算机视觉】二、图像形成——实验:2D变换编辑器2.0(Pygame)

文章目录 一、向量和矩阵的基本运算二、几何基元和变换1、几何基元(Geometric Primitives)2、几何变换(Geometric Transformations)2D变换编辑器0. 项目结构1. Package: guibutton.pywindow.py1. __init__(self, width, height, title)2. add_buttons(self)3. clear(self)4. dr…

WEB前端 HTML 列表表格

列表 有序列表 使用“ol”创建“有序列表”&#xff0c;使用“li”表示“列表项” <body><ol type"1"><li>列表1</li><li>列表2</li><li>列表3</li></ol><ol type"A"><li>列表A<…

Redis进阶——redis消息队列

目录 redis消息队列认识消息队列基于List实现消息队列如何基于List结构模拟消息队列基于List的消息队列有哪些优缺点&#xff1f; 基于PubSub的消息队列基于Stream的消息队列读取消息的方式之一&#xff1a;XREAD基于Stream的消息队列–消费者组redis三种消息队列的对比 Stream…