Gin框架接入Prometheus,grafana辅助pprof检测内存泄露

prometheus与grafana的安装

grom接入Prometheus,grafana-CSDN博客

Prometheus 动态加载

我们想给Prometheus新增监听任务新增ginapp项目只需要在原来的配置文件下面新增ginapp相关metric

在docker compose文件下面新增

执行

docker-compose up -d 
curl -X POST http://localhost:9090/-/reload

granfa配置新的job

配置golang dashboard模版

配置之后我们看以在dashboard看到

Gin框架中间件配置

package initialization

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

func Routers() *gin.Engine {
	r := gin.New()
	r.Use(middware.GinRecovery(true), middware.GinZapLogger())
	r.Use(middware.Cors())
	router.InitOrderRouter(r)
	p := ginprom.New(
		ginprom.Engine(r),
		ginprom.Subsystem("gin"),
	)

	r.Use(p.Instrument())
	return r
}

pprof配置

package router

import (
	"awesomeProject3/api"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/http/pprof"
)

func InitOrderRouter(Router *gin.Engine) {
	Router.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"code":    http.StatusOK,
			"success": true,
		})
	})
	// 定义一个简单的GET路由
	Router.GET("/v1/ping", func(c *gin.Context) {

		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})

	Router.GET("/test", api.TestHandler) //

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

模拟内存泄露

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

对当前接口压测

pprof监控

Grafana监控

我们看到goroutine数量已经爆表了,我的mac风扇开始转了

这个时候可以点击pprof groutine很好定位哪一块出现了内存泄露

结论

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

<think>嗯,用户想要一个Go语言面试简历模板,针对有3年工作经验的人,包括项目详情、技术栈、框架使用和代码示例。首先,我需要回忆一下常见的简历结构和Go开发者的关键点。通常简历分为几个部分:个人信息、技术栈、工作经验、项目经验、教育背景等。 用户特别提到3年经验,所以工作经验部分需要详细说明职责和成就。项目详解需要具体,不能太笼统。技术栈要列出Go相关的框架和工具,比如Gin、Beego,还有数据库、缓存、消息队列等。代码示例可能需要展示Go的特性,比如并发、接口、错误处理等。 然后要考虑用户可能的深层需求。他们可能希望简历能突出实际能力,而不仅仅是列举技术名词。所以项目部分需要量化成果,比如性能提升百分比,优化效果。代码示例要简洁,展示实际应用场景,比如用Gin框架实现路由,或者使用channel处理并发。 另外,用户提到参考了结构化整理知识的方法,这可能意味着他们希望简历结构清晰,重点突出。需要分点说明,使用项目符号,避免大段文字。技术栈部分可以分类,如后端框架、数据库、云服务等,方便面试官快速浏览。 可能还需要注意简历的格式问题,比如使用简洁的排版,适当的缩进,代码示例用等宽字体。不过用户主要需要内容指导,所以重点放在内容的结构和细节上,而不是格式美化。 还要考虑常见的面试问题,比如项目中的挑战、解决方案、技术选型的原因。所以在项目详解中,应该包括项目背景、技术方案、个人职责、成果,以及遇到的难点和解决方案。这样简历不仅展示做了什么,还展示思考过程和解决问题的能力。 最后,代码示例需要简短但具有代表性,比如用Go实现一个HTTP服务,或者并发处理任务的例子。避免太长的代码段,保持关键部分即可,并加上注释说明。</think># Go语言开发工程师简历模板(3年经验) ## 一、技术栈 - **语言**: Go (Gin/Beego/Echo)、Python、Shell - **框架**: Gin (3项目)、Beego (2项目)、gRPC (4项目) - **数据库**: MySQL (分库分表经验)、Redis (集群部署)、MongoDB - **中间件**: RabbitMQ/Kafka、Etcd、Prometheus - **云原生**: Docker (10+容器化项目)、Kubernetes (3个生产集群)、Istio - **工具链**: Go Modules、pprof、go test、Swagger ## 二、项目经验(样例) ### 1. 电商订单系统(2022.03-2023.06) **技术架构**: $$ \begin{cases} \text{Go+Gin+Redis Cluster+MySQL分表} \\ \text{日均处理订单量: 50万+} \\ \text{响应时间: <200ms (P99)} \end{cases} $$ **核心贡献**: 1. 实现订单状态机模块,通过`sync.Map`缓存状态转换规则,QPS提升40%[^1] 2. 设计分库分表方案(32库×64表),使用Gorm自定义分表逻辑 3. 优化Redis热点数据问题,采用`local cache+redis`二级缓存方案 **代码片段**: ```go // 订单状态校验(使用策略模式) func (o *Order) ValidateTransition(newStatus Status) error { transition := o.currentState.TransitionTo(newStatus) if transition == nil { return errors.New("invalid status transition") } return transition.Validate(o) } ``` ### 2. 实时日志分析系统(2021.05-2022.02) **技术亮点**: - Go协程池处理日志流(5000+ goroutines) - 自定义时间轮算法实现滑动窗口统计 - 使用pprof优化内存分配,GC时间降低65% ## 三、框架使用规范 1. **Gin项目结构**: ``` ├── api ├── cmd ├── configs ├── internal │ ├── controller │ ├── middleware │ └── service └── pkg ``` 2. **错误处理模式**: ```go func GetUser(c *gin.Context) { id := c.Param("id") user, err := service.GetUser(id) if errors.Is(err, sql.ErrNoRows) { c.JSON(404, gin.H{"error": "user not found"}) return } c.JSON(200, user) } ``` ## 四、面试准备建议 1. **并发编程**:准备channel死锁案例、sync.Pool使用场景 2. **内存管理**:理解逃逸分析原理,能解释interface底层结构 3. **性能优化**:准备pprof火焰图分析案例,如GC过高的解决方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值