Gonet/http/pprof分析内存泄露及解决过程

Written by

in

文章目录
  • 在go语言中,其自身实现了 GC(垃圾回收)机制, 所有出现内存泄露的原因很大可能是 有些goroutine因为各种各样的原因(如 channel阻塞或未设置close channel的功能)导致 垃圾回收机制 认为这些goroutine还在正常运行,无法被回收(每个goroutine至少占用2KB资源),长时间处理大量请求后,导致内存耗尽。
  • go语言编写的kong插件中,出现内存泄露。
  • 嵌入如下代码; 即使是在 go脚本中,通过如下代码,也会生成一个pprof的http服务,供web端分析使用。 import “github.com/Kong/go-pdk/server” import _ “net/http/pprof” // main 主入口函数,启动go-pdk中的server func main() { // 服务资源分析时使用 go func() { err := http.ListenAndServe(“0.0.0.0:6000”, nil) if err != nil { panic(“启动服务失败”) } }() err := server.StartServer(New, Version, Priority) if err != nil { panic(err) } } 运行服务,并 查看 http://localhost:6000/debug/pprof/goroutine?debug=1 分析方式如下: 压测请求此服务; 对比发现 协程个数不断增加的地方;从而找到内存泄露点;
  • 最终发现 是 链路追踪的jaeger reporter(导出span数据到jaeger中)每次请求进入都新建一个协程,导致内存泄露
  • 通过 全局变量+ sync.Once 保证 只生成一个 jaeger reporter;从而 不会生成多个协程,及 节约 网络io资源。
  • 以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。 您可能感兴趣的文章: 谈谈golang的netpoll原理解析 Golang网络模型netpoll源码解析(具体流程) 如何基于Golang实现Kubernetes边车模式 go标准库net/http服务端的实现示例 golang中的net/http库基本使用详解 浅析Go中fasthttp与net/http的性能对比及应用
  • 目录
    • 内存泄露出现的原因
    • 业务大致场景
    • 分析方法
    • 具体原因
    • 解决方法
    • 总结

    在go语言中,其自身实现了 GC(垃圾回收)机制, 所有出现内存泄露的原因很大可能是 有些goroutine因为各种各样的原因(如 channel阻塞或未设置close channel的功能)导致 垃圾回收机制 认为这些goroutine还在正常运行,无法被回收(每个goroutine至少占用2KB资源),长时间处理大量请求后,导致内存耗尽。

    go语言编写的kong插件中,出现内存泄露。

    嵌入如下代码; 即使是在 go脚本中,通过如下代码,也会生成一个pprof的http服务,供web端分析使用。

    import "github.com/Kong/go-pdk/server"
    import _ "net/http/pprof"
    
    
    // main 主入口函数,启动go-pdk中的server
    func main() {
    	// 服务资源分析时使用
    	go func() {
    		err := http.ListenAndServe("0.0.0.0:6000", nil)
    		if err != nil {
    			panic("启动服务失败")
    		}
    	}()
    
    	err := server.StartServer(New, Version, Priority)
    	if err != nil {
    		panic(err)
    	}
    }

    运行服务,并 查看 http://localhost:6000/debug/pprof/goroutine?debug=1 分析方式如下:

    压测请求此服务; 对比发现 协程个数不断增加的地方;从而找到内存泄露点;

    最终发现 是 链路追踪的jaeger reporter(导出span数据到jaeger中)每次请求进入都新建一个协程,导致内存泄露

    通过 全局变量+ sync.Once 保证 只生成一个 jaeger reporter;从而 不会生成多个协程,及 节约 网络io资源。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。

    您可能感兴趣的文章:

    • 谈谈golang的netpoll原理解析
    • Golang网络模型netpoll源码解析(具体流程)
    • 如何基于Golang实现Kubernetes边车模式
    • go标准库net/http服务端的实现示例
    • golang中的net/http库基本使用详解
    • 浅析Go中fasthttp与net/http的性能对比及应用

    站内搜索