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超时控制,做好超时熔断措施,做好监控警告,下游基础设施如果达到瓶颈,我们可对下游基础进行主从 水平扩容等。

相关推荐
Yeats_Liao5 小时前
Go Web 编程快速入门 13 - 部署与运维:Docker容器化、Kubernetes编排与CI/CD
运维·前端·后端·golang
Yeats_Liao5 小时前
Go Web 编程快速入门 14 - 性能优化与最佳实践:Go应用性能分析、内存管理、并发编程最佳实践
前端·后端·性能优化·golang
QX_hao7 小时前
【Go】--接口(interface)
开发语言·后端·golang
qqxhb7 小时前
系统架构设计师备考第61天——嵌入式系统架构模式&操作系统&数据库&中间件
数据库·中间件·系统架构·sqlite·dds·层次化(封闭/开放)·递归模式
不爱笑的良田7 小时前
从零开始的云原生之旅(一):把 Go 应用塞进 Docker
docker·云原生·golang
数据知道9 小时前
Go语言设计模式:桥接模式详解
设计模式·golang·桥接模式
Wenhao.10 小时前
LeetCode LRU缓存
算法·leetcode·缓存·golang
数据知道13 小时前
Go语言设计模式:原型模式详解
设计模式·golang·原型模式
千码君201613 小时前
Go语言:常量计数器iota的意义
开发语言·后端·golang·状态码·const·iota·常量
ttghgfhhjxkl16 小时前
《macOS 配置 GO 语言后,如何切换不同 GO 版本?》
开发语言·macos·golang