go程序中使用pprof增加程序监控功能

1.什么是 pprof?
pprof 是 Go 内置的性能分析工具,用于生成程序运行时的性能分析数据。它可以帮助开发者分析:

CPU 使用情况
内存分配情况
Goroutine 状况
系统调用分析等
2. 如何使用 pprof?
要使用 pprof,首先需要在 Go 代码中引入 net/http/pprof 包,并启动一个 HTTP 服务器以提供性能分析接口。

  1. 使用 pprof 分析 Go 程序
    启动 Go 程序:

go run main.go
启动程序后,访问 http://localhost:6060/debug/pprof/,查看提供的接口。

假设你要分析 30 秒的 CPU 性能:

go tool pprof http://localhost:6060/debug/pprof/cpu?seconds=30
运行后,下载到本地的 CPU 分析数据文件为 cpu.pprof,然后可以使用 go tool pprof 进一步分析。

例如,使用以下命令查看分析结果:

go tool pprof cpu.pprof
在 pprof 的交互界面中,你可以输入 top 查看 CPU 消耗最多的函数,或者使用 web 生成 SVG 图形查看分析结果。

示例代码如下:

package util
import (log "github.com/sirupsen/logrus""net/http""runtime""strconv""sync""github.com/gorilla/mux""net/http/pprof"
)// 定义全局 pprof 控制开关和互斥锁
var (enablePprof   boolenablePprofMu sync.MutexblockRate     int        // 新增阻塞采样率mutexFraction int        // 新增互斥锁采样比例configMu      sync.Mutex // 新增配置锁
)func InitPprof() {// 初始化 pprof 状态enablePprof = false// 创建路由器r := mux.NewRouter()// 注册 pprof 相关路由//curl http://localhost:6060/debug/pprof/enbaler.HandleFunc("/debug/pprof/enable", pprofEnableHandler)//curl http://localhost:6060/debug/pprof/disabler.HandleFunc("/debug/pprof/disable", pprofDisableHandler)// 新增配置接口//curl http://localhost:6060/debug/pprof/set-block-rate?rate=1000r.HandleFunc("/debug/pprof/set-block-rate", setBlockRateHandler)//curl http://localhost:6060/debug/pprof/set-mutex-fraction?fraction=1r.HandleFunc("/debug/pprof/set-mutex-fraction", setMutexFractionHandler)// 启动 pprof 服务go startPprofServer(r)
}// 新增阻塞采样率设置处理器
//  rate值	实际采样间隔	    适用场景
//    0	     完全禁用	    生产环境默认配置
//    1	  记录所有阻塞事件	    精确调试但性能开销最大
//   1000  约1微秒采样一次    平衡精度与开销的通用配置
//   1e6   约1毫秒采样一次    高并发场景下的低开销采样配置
func setBlockRateHandler(w http.ResponseWriter, r *http.Request) {rate, err := strconv.Atoi(r.URL.Query().Get("rate"))if err != nil || rate < 0 {http.Error(w, "Invalid rate parameter", http.StatusBadRequest)return}configMu.Lock()defer configMu.Unlock()blockRate = rateruntime.SetBlockProfileRate(blockRate)if _, err := w.Write([]byte("Block profile rate updated")); err != nil {log.Errorf("Failed to write enable response: %v", err)}
}// 新增互斥锁采样设置处理器
//行为逻辑:
//当参数fraction ≤ 0 时:关闭互斥锁采样
//当参数fraction = 1 时:记录所有互斥锁争用事件
//当参数fraction > 1 时:按比例采样(例如设为4时,每4次争用事件采样1次)
func setMutexFractionHandler(w http.ResponseWriter, r *http.Request) {fraction, err := strconv.Atoi(r.URL.Query().Get("fraction"))if err != nil || fraction < 0 {http.Error(w, "Fraction must be 0 or 1", http.StatusBadRequest)return}configMu.Lock()defer configMu.Unlock()mutexFraction = fractionruntime.SetMutexProfileFraction(mutexFraction)if _, err := w.Write([]byte("Mutex profile fraction updated")); err != nil {log.Errorf("Failed to write enable response: %v", err)}
}// 启动 pprof 服务
func startPprofServer(r *mux.Router) {pprofRouter := r.PathPrefix("/debug/pprof/").Subrouter()// 通用包装函数wrapPprofHandler := func(handler http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {checkAndHandlePprof(w, r, handler)}}// 注册标准路径(经过包装)pprofRouter.HandleFunc("/", wrapPprofHandler(pprof.Index))pprofRouter.HandleFunc("/cmdline", wrapPprofHandler(pprof.Cmdline))pprofRouter.HandleFunc("/profile", wrapPprofHandler(pprof.Profile))pprofRouter.HandleFunc("/symbol", wrapPprofHandler(pprof.Symbol))pprofRouter.HandleFunc("/trace", wrapPprofHandler(pprof.Trace))// 注册特殊路径(经过包装)profiles := []string{"allocs", "heap", "goroutine", "block", "mutex", "threadcreate"}for _, profile := range profiles {pprofRouter.Handle("/"+profile,wrapPprofHandler(pprof.Handler(profile).ServeHTTP), // 关键修改)}// 启动 pprof 监听if err := http.ListenAndServe(":6060", r); err != nil {log.Errorf("pprof server failed: %v", err)}
}func pprofEnableHandler(w http.ResponseWriter, r *http.Request) {enablePprofMu.Lock()defer enablePprofMu.Unlock()enablePprof = trueif _, err := w.Write([]byte("pprof enabled")); err != nil {log.Errorf("Failed to write enable response: %v", err)}
}func pprofDisableHandler(w http.ResponseWriter, r *http.Request) {enablePprofMu.Lock()defer enablePprofMu.Unlock()enablePprof = false// 关闭互斥锁以及阻塞采样runtime.SetBlockProfileRate(0)runtime.SetMutexProfileFraction(0)if _, err := w.Write([]byte("pprof disabled")); err != nil {log.Errorf("Failed to write disable response: %v", err)}}// 检查 pprof 启用状态并处理请求
func checkAndHandlePprof(w http.ResponseWriter, r *http.Request, handler func(http.ResponseWriter, *http.Request)) {enablePprofMu.Lock()defer enablePprofMu.Unlock()if !enablePprof {http.Error(w, "pprof is disabled", http.StatusForbidden)return}handler(w, r)
}

之后在main函数中启动:

	util2.InitPprof()

其中github.com/gorilla/mux 是 Go 语言中的一个非常流行的路由(Router)包,它提供了一个强大的 HTTP 路由器,能够帮助开发者更方便地定义 HTTP 路由规则,进行 URL 路由匹配、请求处理等操作
例如:

package mainimport ("fmt""log""net/http""github.com/gorilla/mux"
)// 处理根路由
func HomeHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Welcome to the Home Page!")
}// 处理带有路径变量的路由
func UserHandler(w http.ResponseWriter, r *http.Request) {vars := mux.Vars(r)userId := vars["id"]fmt.Fprintf(w, "User ID: %s\n", userId)
}// 处理查询参数的路由
func ArticleHandler(w http.ResponseWriter, r *http.Request) {query := r.URL.Query().Get("query")fmt.Fprintf(w, "Article Search Query: %s\n", query)
}func main() {// 创建一个新的路由器r := mux.NewRouter()// 定义路由规则r.HandleFunc("/", HomeHandler)r.HandleFunc("/user/{id:[0-9]+}", UserHandler) // 路径中带有动态变量 idr.HandleFunc("/article", ArticleHandler)      // 路由匹配查询参数// 启动 HTTP 服务器log.Println("Starting server on :8080")log.Fatal(http.ListenAndServe(":8080", r))
}

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

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

相关文章

javaweb自用笔记:Vue

Vue 什么是vue vue案例 1、引入vue.js文件 2、定义vue对象 3、定义vue接管的区域el 4、定义数据模型data 5、定义视图div 6、通过标签v-model来绑定数据模型 7、{{message}}直接将数据模型message展示出来 8、由于vue的双向数据绑定&#xff0c;当视图层标签input里的…

376_C++_云透传,板端负责处理透传数据的API函数,用于实现客户端对设备内部接口的访问(VMS把数据直接传给板端内部)

RsApi_PassThrough 云透传,板端负责处理透传数据的API函数,用于实现客户端对设备内部接口的访问(VMS把数据直接传给板端内部) 我来分析一下 RsApi_PassThrough 函数的作用和实现逻辑: 1. 功能概述 RsApi_PassThrough 是一个透传接口,用于处理 /API/Http/PassThrough 的…

基于eRDMA实测DeepSeek开源的3FS

DeepSeek昨天开源了3FS分布式文件系统, 通过180个存储节点提供了 6.6TiB/s的存储性能, 全面支持大模型的训练和推理的KVCache转存以及向量数据库等能力, 每个客户端节点支持40GB/s峰值吞吐用于KVCache查找. 发布后, 我们在阿里云ECS上进行了快速的复现, 并进行了性能测试, ECS…

计算机毕业设计SpringBoot+Vue.js医院挂号就诊系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Linux的用户与权限--第二天

认知root用户&#xff08;超级管理员&#xff09; root用户用于最大的系统操作权限 普通用户的权限&#xff0c;一般在HOME目录内部不受限制 su与exit命令 su命令&#xff1a; su [-] 用户名 -符号是可选的&#xff0c;表示切换用户后加载环境变量 参数为用户名&#xff0c…

计算机网络软考

1.物理层 1.两个主机之间发送数据的过程 自上而下的封装数据&#xff0c;自下而上的解封装数据&#xff0c;实现数据的传输 2.数据、信号、码元 码元就是数字通信里用来表示信息的基本信号单元。比如在二进制中&#xff0c;用高电平代表 “1”、低电平代表 “0”&#xff0c…

第四十一:Axios 模型的 get ,post请求

Axios 的 get 请求方式 9.双向数据绑定 v-model - 邓瑞编程 Axios 的 post 请求方式&#xff1a;

【JQuery—前端快速入门】JQuery 操作元素

JQuery 操作元素 1. 获取/修改元素内容 三个简单的获取元素的方法&#xff1a; 这三个方法即可以获取元素的内容&#xff0c;又可以设置元素的内容. 有参数时&#xff0c;就进行元素的值设置&#xff0c;没有参数时&#xff0c;就进行元素内容的获取. 接下来&#xff0c;我们需…

2025年4月1日-2日AutoCable 中国汽车线束线缆及连接技术创新峰会即将开幕

正如人体的心脏与四肢之间需要靠神经和血管连接&#xff0c;汽车的各个部件&#xff0c;也要靠各种电线、管道连接。线束&#xff0c;就是汽车的神经和血管&#xff0c;车主向汽车下达的每一个功能指令&#xff0c;都通过线束来传递&#xff0c;看似不起眼的线束&#xff0c;却…

编程题 - 汽水瓶【JavaScript/Node.js解法】

目录 题目描述 解题思路 代码实现 复杂度分析 代码解释 输入输出处理 题目描述 有这样一道经典的编程题&#xff1a;某商店规定&#xff1a;三个空汽水瓶可以换一瓶汽水。小张手上有 n 个空汽水瓶&#xff0c;他最多可以换多少瓶汽水喝&#xff1f; 解题思路 这是一个…

深度学习神经网络分类原理

每一个神经元做的是一个类似回归的操作 最后一层是softmax函数&#xff0c;每一个输出就会变成一个0到1之间的数&#xff0c;也就是概率&#xff0c;然后他们之间的和加起来等于1&#xff0c;到底是哪一个分类就是看哪个神经元的这个值最大。 那么如何算损失呢&#xff1a; 加…

硬核技术组合!用 DeepSeek R1、Ollama、Docker、RAGFlow 打造专属本地知识库

文章目录 一、引言二、安装Ollama部署DeepSeekR1三、安装Docker四、安装使用RAGFlow4.1 系统架构4.2 部署流程4.3 使用RAGFlow4.4 在RAGFlow中新增模型4.5 创建知识库4.6 创建私人助理使用RGA 一、引言 本地部署DeepSeek R1 Ollama RAGFlow构建个人知识库&#xff0c;通过将…

前端实现OSS上传图片(Vue3+vant)

首先&#xff0c;下面这些信息从阿里云服务器OSS管理中获取 aliyun:oss:file:endpoint: "oss-cn-beijing.aliyuncs.com"keyid: "xxxxxxxxx"keysecret: "xxxxxxxxxxxx"bucketname: "xxxx"一、安装OSS npm install ali-oss 二、以下步…

huggingface NLP主要知识点以及超级详解使用

1.安装huggingface依赖库 pip install transformers pip install datasets pip install pytorch pip install tokenizers pip install diffusers pip install accelerate pip install evaluate pip install optimum pip install pillow pip install requests pip install gr…

Spark核心之02:常用算子详解

1、RDD操作详解 # 启动spark-shell spark-shell --master local[2] 1.1 基本转换 1) map map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD。 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应。 举例&#xff1a; scala> val a sc.parallelize(1 …

MySQL 8.X 报错处理

1.重新加载配置 reload the configuration mysql> ALTER INSTANCE RELOAD KEYRING; ERROR 1227 (42000): Access denied; you need (at least one of) the ENCRYPTION_KEY_ADMIN privilege(s) for this operation 提示需要ENCRYPTION_KEY_ADMIN权限 重新授权 GRANT ENCR…

SQL注入练习场:PHPStudy+SQLI-LABS靶场搭建教程(零基础友好版)

注意&#xff1a;文中涉及演示均为模拟测试&#xff0c;切勿用于真实环境&#xff0c;任何未授权测试都是违法行为&#xff01; 一、环境准备 下载PHPStudy 官网下载地址&#xff1a;https://www.xp.cn/php-study&#xff08;选择Windows版&#xff09; 安装时建议选择自定…

现今大语言模型性能(准确率)比较

现今大语言模型性能(准确率)比较 表头信息:表的标题为“大语言模型性能比较结果”(英文:Table 1: Large Language Model Performance Comparison Results),表明该表是用于对比不同大语言模型的性能。列信息: 模型:列出参与比较的不同大语言模型名称,包括LLAMA3(70B)…

Docker创建自定义网桥并指定网段

前言 docker0是Docker默认网络的核心组件, 通过虚拟网桥和NAT技术, 实现了容器间的通信以及容器与外部网络的交互。然而, docker0网段是固定的(通常是172.17.0.0/16), 为了更灵活地管理容器网络&#xff0c;Docker支持创建自定义网桥&#xff0c;允许用户指定网段。 例如, 在…

【向量数据库Weaviate】 和Elasticsearch的区别

Weaviate 和 Elasticsearch 是两种不同类型的数据库&#xff0c;设计目标和应用场景有显著差异。以下是它们的核心区别和适用场景的详细对比&#xff1a; 1. 设计目标与核心能力 维度WeaviateElasticsearch核心能力向量数据库 图数据库&#xff08;语义搜索优先&#xff09;全…