内存泄露出现的原因
在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资源。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
来源:互联网
免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作! |