Gin框架接入pyroscope完美替代pprof实现检测内存泄露

传统检测内存泄露可以看一下我这篇文章Gin框架接入Prometheus,grafana辅助pprof检测内存泄露-CSDN博客

pyroscope被Grafana收购,GPT来总结一下pyroscope的强大之处🐶

pyroscope github地址

pyroscope与grafana的安装

docker compose安装,这里我们其实可以不使用grafana,pyroscope已经是一个很完整的产品,但是我们在grafana里面可以配置数据源,也可以在grafana里面查看,grafana暂时还没有好的pyroscope dashboard

复制代码
version: '3.8'

services:


  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "3000:3000"
    networks:
      - monitoring
    depends_on:
      - prometheus



  pyroscope:
    image: grafana/pyroscope
    container_name: pyroscope
    ports:
      - "4040:4040"
    networks:
      - monitoring    

networks:
  monitoring:
    driver: bridge

执行

复制代码
docker-compose up -d 

访问Pyroscopehttp://localhost:4040/ 我们可以看到go语言的各种性能指标与pprof检测的各类指标差不多

Gin框架中间件配置

我们在gin框架中间件中集成这个检测插件

ApplicationName: "simple.golang.app.golang",用于在Pyroscope筛选服务

复制代码
package initialization

import (
	"awesomeProject3/middware"
	"awesomeProject3/router"
	"github.com/Depado/ginprom"
	"github.com/gin-gonic/gin"
	"github.com/grafana/pyroscope-go"
	_ "net/http/pprof"
	"runtime"
)

func Routers() *gin.Engine {
	r := gin.New()

	r.Use(p.Instrument())
	runtime.SetMutexProfileFraction(5)
	runtime.SetBlockProfileRate(5)

	pyroscope.Start(pyroscope.Config{
		ApplicationName: "simple.golang.app.golang",
		// replace this with the address of pyroscope server
		ServerAddress: "http://localhost:4040",
		// you can disable logging by setting this to nil
		Logger: pyroscope.StandardLogger,
		// you can provide static tags via a map:
		Tags: map[string]string{"hostname": "ginapp"},

		ProfileTypes: []pyroscope.ProfileType{
			// these profile types are enabled by default:
			pyroscope.ProfileCPU,
			pyroscope.ProfileAllocObjects,
			pyroscope.ProfileAllocSpace,
			pyroscope.ProfileInuseObjects,
			pyroscope.ProfileInuseSpace,

			// these profile types are optional:
			pyroscope.ProfileGoroutines,
			pyroscope.ProfileMutexCount,
			pyroscope.ProfileMutexDuration,
			pyroscope.ProfileBlockCount,
			pyroscope.ProfileBlockDuration,
		},
	})
	return r
}

模拟内存泄露

我们来模拟内存泄露 对下面接口压测,压测粒度小一点,来看pyroscope的作用。

我们生产项目中出现过一次严重的内存泄露,例子如下图所示,该接口qps非常高

pyroscope监控查看内存泄露

我们点击Single可以看到详细的火焰图以及性能瓶颈,内存泄露的方法集代码,也就是产生goroutine泄露的地方

结论

我们在使用golang 高并行处理下游任务的时候,一定要对下游基础设施要有敬畏之心,调用时限制goroutine的运行数量并且设置上context超时控制,做好超时熔断措施,做好监控警告,下游基础设施如果达到瓶颈,我们可对下游基础进行主从 水平扩容等。

相关推荐
roman_日积跬步-终至千里1 小时前
【Go语言基础【14】】defer与异常处理(panic、recover)
golang
孔令飞2 小时前
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
ai·云原生·容器·golang·kubernetes
我的golang之路果然有问题7 小时前
云服务器部署Gin+gorm 项目 demo
运维·服务器·后端·学习·golang·gin
孔令飞8 小时前
Go 为何天生适合云原生?
ai·云原生·容器·golang·kubernetes
YGGP12 小时前
吃透 Golang 基础:数据结构之 Map
开发语言·数据结构·golang
march of Time12 小时前
go工具库:hertz api框架 hertz client的使用
开发语言·golang·iphone
余厌厌厌13 小时前
go语言学习 第9章:映射(Map)
服务器·学习·golang
roman_日积跬步-终至千里13 小时前
【Go语言基础【15】】数组:固定长度的连续存储结构
golang
cccc来财14 小时前
Go中的协程并发和并发panic处理
开发语言·后端·golang
roman_日积跬步-终至千里1 天前
【Go语言基础【9】】字符串格式化与输入处理
golang