golang入门笔记——pprof性能分析

news2024/12/27 11:18:26

文章目录

  • 简介
  • runtime/pprof的使用
  • 命令行交互
  • 网络服务性能分析
  • pprof与性能测试结合
  • 压测工具go-wrk

简介

golang性能分析工具pprof的8个指标

1.性能分析的5个方面:CPU、内存、I/O、goroutine(协程使用情况和泄漏检查)、死锁检测以及数据竟态分析

	runtime.SetMutexProfileFraction(1) //开启对锁调用的跟踪 mutex
	runtime.SetBlockProfileRate(1)     //开启对阻塞操作的跟踪

2.两种程序性能指标采集

runtime/pprof:采集工具型应用运行数据进行分析
net/http/pprof:采集服务型应用运行时数据进行分析

pprof开启后,每隔一段时间(10ms)就会收集下当前的堆栈信息,获取各个函数占用的CPU以及内存资源;最后通过对这些采样数据进行分析,形成一个性能分析报告。

3.交互式终端性能分析

不管是工具型应用还是服务型应用,我们使用相应的pprof库获取数据之后,下一步的都要对这些数据进行分析,我们可以使用go tool pprof命令行工具。

go tool pprof [binary] [source]
#binary是应用的二进制文件,用来解析各种符号
#source标识profile数据的来源,可以是本地的文件,也可以是http地址

4.web网页性能分析

如果你的应用程序是一直运行的,比如 web 应用,那么可以使用net/http/pprof库,它能够在提供   HTTP 服务进行分
析。
如果使用了默认的http.DefaultServeMux(通常是代码直接使用 http.ListenAndServe(“0.0.0.0:8000”,  nil)),只需要
在你的web server端代码中按如下方式导入net/http/pprof

如果你使用自定义的 Mux,则需要手动注册一些路由规则:

r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)

如果你使用的是gin框架,那么推荐使用github.com/gin-contrib/pprof,在代码中通过以下命令注册pprof相关路由。

pprof.Register(router)

访问地址:http://host:port/debug/pprof会出现性能分析的网页

这个路径下还有几个子页面:

/debug/pprof/profile:访问这个链接会自动进行 CPU profiling,持续 30s,并生成一个文件供下载
/debug/pprof/heap: Memory Profiling 的路径,访问这个链接会得到一个内存 Profiling 结果的文件
/debug/pprof/block:block Profiling 的路径
/debug/pprof/goroutines:运行的 goroutines 列表,以及调用关系

runtime/pprof的使用

代码:

package main

import (
	"flag"
	"fmt"
	"os"
	"runtime/pprof"
	"time"
)

func logicCode() {
	var c chan int
	for {
		select {
		case v := <-c:
			fmt.Printf("recv from chan, value:%v\n", v)
		default:

		}
	}
}

func main() {
	var isCPUPprof bool
	var isMemPprof bool

	flag.BoolVar(&isCPUPprof, "cpu", false, "turn cpu pprof on")
	flag.BoolVar(&isMemPprof, "mem", false, "turn mem pprof on")
	flag.Parse()

	if isCPUPprof {
		file, err := os.Create("./cpu.pprof")
		if err != nil {
			fmt.Println("create cpu pprof failed,err:", err)
			return
		}
		pprof.StartCPUProfile(file) 
		defer file.Close()
		defer pprof.StopCPUProfile()
	}
	for i := 0; i < 8; i++ {
		go logicCode()
	}
	time.Sleep(20 * time.Second)
	if isMemPprof {
		file, err := os.Create("./mem.pprof")
		if err != nil {
			fmt.Println("create mem pprof failed,err:", err)
			return
		}
		pprof.WriteHeapProfile(file)
		file.Close()
	}
}

命令行交互

使用go工具链里的pprof来进行分析

go tool pprof cpu.pprof
#go tool pprof http://127.0.0.1:8000/debug/pprof/profile

在这里插入图片描述

topN来获取占用CPU前几位的函数:

top3 #获取占用CPU前3位的函数

在这里插入图片描述
flat:当前函数占用CPU的耗时
flat%:当前函数占用CPU耗时占总CPU耗时的百分比
sum%:函数占用CPU的耗时累计百分比
cum:当前函数加上当前函数调用函数占用CPU的总耗时
cum %:当前函数加上当前函数调用函数占用CPU总耗时百分比
最后一列:函数的名称

list 函数名,查看具体的函数分析

list logicCode

在这里插入图片描述
可以看出函数的所有耗时都在 case v:=<-c这条语句的执行中。

网络服务性能分析

package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"strings"
)

func main() {
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		r.ParseForm()
		fmt.Println(r.Form)
		fmt.Println("path:", r.URL.Path)
		fmt.Println("scheme:", r.URL.Scheme)
		for k, v := range r.Form {
			fmt.Println("key:", k)
			fmt.Println("val:", strings.Join(v, ""))
		}
		w.Write([]byte("hello world"))
	})
	http.ListenAndServe("127.0.0.1:8080", nil)
}

第一种方式:

#分析5s内对应服务的性能
go tool pprof -seconds=5 http://127.0.0.1:8080/debug/pprof/profile 
#go tool pprof -seconds=5 http://127.0.0.1:8080/debug/pprof/heap

第二种方式:

下载原始数据文件到XXX-X.out目录,对于一些需要累计到一些时间才能采集的指标,我们可以使用?seconds=X来设置
curl -o XXX-X.out http://127.0.0.1:8080/debug/pprof/XXX?seconds=X

#获取10s内内存的使用情况
curl -o profile.out http://127.0.0.1:8080/debug/pprof/heap?seconds=10
go tool pprof profile.out

在这里插入图片描述

对gin服务进行性能分析

package main

import (
	"fmt"
	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/hello", func(c *gin.Context) {
		var ch chan int
		select {
		case v := <-ch:
			fmt.Println(v)
		default:

		}
	})
	pprof.Register(r)
	r.Run()
}

访问网址:http://localhost:8080/debug/pprof
在这里插入图片描述
3 allocs:表示过去进行过3次内存分配
0 block:表示0个阻塞
0 cmdline:执行的命令行
4 goroutine:创建的goroutine数量
3 heap:3个活动中的对象内存分配情况
0 mutex:当前锁竞争的数量
0 profile:cpu使用情况进行采用,默认采样30s,后面加参数seconds=60来指定时间
5 threadcreate:线程的创建数
0 trace:整个程序的运行过程的跟踪

pprof与性能测试结合

go test命令有两个参数和pprof相关,它们分别指定生成的CPU和Memory profiling保存的文件

-cpuprofile: cpu profiling数据要保存的文件地址
-memprofile:memory profiling数据要保存的文件地址
go test -bench . -cpuprofile=cpu.prof

go test -bench . -memprofile=./mem.prof


go test -bench . -blockprofile=./block.prof

压测工具go-wrk

go-wrk的包的下载

go get github.com/adeven/go-wrk

go-wrk的使用格式

go-wrk [flags] url

常用参数:

-H="User-Agent: go-wrk 0.1 bechmark\nContent-Type: text/html;":'\n'分隔的请求头
-c=100: 使用的最大连接数
-k=true: 是否禁用keep-alives
-i=false: if TLS security checks are disabled
-m="GET": HTTP请求方法
-n=1000: 请求总数
-t=1: 使用的线程数
-b="" HTTP请求体
-s="" 如果指定,它将计算响应中包含搜索到的字符串s的频率
go-wrk -t=8 -c=100 -n=10000 "http://127.0.0.1:8080/api/v1/posts?size=10"

输出结果


==========================BENCHMARK==========================
URL:                            http://127.0.0.1:8080/api/v1/posts?size=10

Used Connections:               100
Used Threads:                   8
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              2.74s
Avg time per request:           27.11ms
Requests per second:            3644.53
Median time per request:        26.88ms
99th percentile time:           39.16ms
Slowest time for request:       45.00ms

=============================DATA=============================
Total response body sizes:              340000
Avg response body per request:          34.00 Byte
Transfer rate per second:               123914.11 Byte/s (0.12 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)

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

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

相关文章

JavaBean文字格斗游戏之进阶版

以上都是关于role类的定义 求赞!

go 内存泄露

事件回顾 9.15号晚18点服务端发版9.16号晚21点监控显示自发版后服务器 TCP_alloc 指标一路飙升至40K(如图) 问题分析 看到 tcp_alloc 指标异常&#xff0c;初步怀疑有tcp连接创建后未关闭&#xff0c;应该是上次发版写了什么代码导致的。回顾此次发版清单&#xff0c;问题应该…

IBM LSF 任务调度系统的主要术语和概念

LSF 术语和概念 了解 IBM LSF 基本术语和概念。 作业状态 IBM Spectrum LSF 作业具有多个状态。 PEND 正在队列中等待调度和分派。 RUN 已分派到主机并正在运行。 DONE 正常完成&#xff0c;退出值为零。 EXIT 已完成&#xff0c;具有非零退出值。 PSUSP 作业处于暂…

FBX文件结构解读【文本格式】

FBX 格式几乎受到所有 3D 引擎的支持&#xff0c;是 Autodesk 开发的 3D 模型的专有格式。它支持顶点、索引、法线、UV坐标、材质和动画。 FBX还支持许多其他类型的信息&#xff0c;但它们对游戏引擎几乎没有用处。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 有两种…

【C++】String类基本接口介绍及模拟实现(多看英文文档)

string目录 如果你很赶时间&#xff0c;那么就直接看我本标题下的内容即可&#xff01;&#xff01; 一、STL简介 1.1什么是STL 1.2STL版本 1.3STL六大组件 1.4STL重要性 1.5如何学习STL 二、什么是string&#xff1f;&#xff1f;&#xff08;本质上是一个类&#xff0…

Leetcode | 303.区域和检索-数组不可变

303.区域和检索-数组不可变 欢迎关注公众号“三戒纪元” 题目 给定一个整数数组 nums&#xff0c;处理以下类型的多个查询: 计算索引 left 和 right &#xff08;包含 left 和 right&#xff09;之间的 nums 元素的 和 &#xff0c;其中 left < right 实现 NumArray 类&a…

24个Docker常见问题处理技巧

1.Docker 迁移存储目录 默认情况系统会将 Docker 容器存放在 var/lib/docker 目录下 [问题起因] 今天通过监控系统&#xff0c;发现公司其中一台服务器的磁盘快慢&#xff0c;随即上去看了下&#xff0c;发现 /var/lib/docker这个目录特别大。 由上述原因&#xff0c;我们都知…

低代码技术推动能源行业数字化转型,服务商模式带来转型新商机

“新能源企业通过数字化转型不仅可以提高企业的运营效率和市场竞争力&#xff0c;还可以创新商业模式、提高能源生产效率和可持续性、优化资源配置并适应市场需求。选择百数的服务商模式&#xff0c;不仅可以解决我们想实现数字化转型的需求&#xff0c;还让我们多了一个开展新…

计算机毕设 python图像检索系统设计与实现

文章目录 0 前言1 课题简介2 图像检索介绍(1) 无监督图像检索(2) 有监督图像检索 3 图像检索步骤4 应用实例5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&am…

uniapp——ios证书申请——详细步骤+遇到的坑——技能提升

三年前&#xff0c;我曾经写过uniapp的程序&#xff0c;时隔三年&#xff0c;又遇到了uniapp的需求&#xff0c;之前没有自行申请ios证书&#xff0c;现在终于要自己生成证书了。。。 是福不是祸&#xff0c;是祸躲不过。 uniapp生成ios证书的详细步骤 uniapp对接unipush的操作…

Revopoint的3D输出格式及转换工具

在 CES 展会期间&#xff0c;许多参观者向我们询问与我们的 3D 扫描仪相关的问题。 最常见的问题包括我们的扫描仪导出的文件格式&#xff0c;以及该文件是否与 3D 打印机兼容&#xff1f; 因此&#xff0c;我们决定回答这些问题&#xff0c;并在本文中对常见的 3D 文件格式进行…

notepad++配合正则表达式分组模式处理文本转化为sql语句

一、正则分组知识点补充 正则分组和捕获 ()&#xff1a;用于分组和捕获子表达式。 大白话就是()匹配到的数据&#xff0c;通过美元符号加下标可以获取该数据&#xff0c;例如$1、$2, 下标从1开始。 下面的案例就采用该模式处理文本数据 二、使用正则的需求背景 有一份报表…

Verilog:$readmemb和$readmemh系统函数的使用与其中的初始化地址相关问题(详细细节)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 $readmemb和$readmemh两个系统函数用于将文件中的数据加载到存储器或者被称为数组的memory中。首先给出他们的语法的BNF范式&#xff0c;有关BNF范式的内容可以在…

GaussDB技术解读系列:性能调优

近日&#xff0c;在第14届中国数据库技术大会&#xff08;DTCC2023&#xff09;的GaussDB“五高两易”核心技术&#xff0c;给世界一个更优选择专场&#xff0c;华为数据库技术专家李士福详细解读了GaussDB性能调优的相关技术和应用实践。 本篇为大家分享GaussDB性能调优的实践…

【MySQL 45讲笔记】

文章目录 第一讲&#xff1a;一条SQL查询语句是如何执行的&#xff1f;第二讲&#xff1a;一条SQL更新语句是如何执行的&#xff1f;第三讲&#xff1a;事务隔离&#xff0c;为什么你改了我还看不见第四讲&#xff1a;深入浅出索引&#xff08;上&#xff09;第五讲&#xff1a…

Python函数绘图与高等代数互溶实例(二): 闪点函数

Python函数绘图与高等代数互溶实例(一):正弦函数与余弦函数 Python函数绘图与高等代数互溶实例(二):闪点函数 Python函数绘图与高等代数互溶实例(二):设置X|Y轴|网格线 一: 函数plot(),展示变量的变化趋势 import numpy as np import matplotlib.pyplot as plt from pylab i…

商家收款一万手续费多少

目前微信和支付宝作为主流的支付平台&#xff0c;为商家提供了安全、便捷的支付解决方案。但是在正常情况下&#xff0c;商家需要向平台支付交易额0.6%至1%不等的手续费&#xff0c;这个费率看似很少&#xff0c;但长期积累下来的手续费支出也是一笔不小的开支。 什么是收款手…

复习Day01:数组part01:701. 二分查找、35. 搜索插入位置、367. 有效的完全平方数、69. x的平方根、74. 搜索二维矩阵

之前的blog链接&#xff1a;https://blog.csdn.net/weixin_43303286/article/details/131690654?spm1001.2014.3001.5501 我用的方法是在leetcode再过一遍例题&#xff0c;明显会的就复制粘贴&#xff0c;之前没写出来就重写&#xff0c;然后从拓展题目中找题目来写。辅以Lab…

UI设计和平面设计的区别是什么?看完这篇一次搞懂

很多想要从事视觉领域工作的新手设计师&#xff0c;搞不懂UI设计和平面设计的区别&#xff1b;也有很多平面设计师工作后想转UI&#xff0c;却不知道该如何进行&#xff0c;导致择业和职业发展受阻&#xff0c;其实核心问题还是因为没有弄清楚UI设计和平面设计的区别是什么。 …

电工-三极管主要参数(直流、交流、极限)

三极管主要参数&#xff08;直流、交流、极限&#xff09; 三极管的主要参数分为三种&#xff0c;即直流参数、交流参数和极限参数&#xff0c;下面分别介绍&#xff1a; 直流参数 共发射极直流放大倍数βIc/Ib 集电极—基极反向截止电流Icbo&#xff0c;Ic0时&#xff0c;…