首页 > 其他分享 >goroutine泄漏检测神器---goleak

goroutine泄漏检测神器---goleak

时间:2022-08-22 15:46:16浏览次数:43  
标签:goroutine Stack --- goleak func go stack

 

goroutine泄漏检测神器---goleak
在日常开发中,go 出去的goroutine通常伴随着死循环,这些goroutine可能处于阻塞状态,一直运行,直到进程结束。

对于线上服务来说,一直是在运行的,除非panic重启等,不然一旦出现goroutine泄漏,资源被一直占用,cpu/内存将会直线陡增,对于线上服务影响巨大,通常出了问题,可以采用pprof来进行分析,日常开发中,如果能做到边开发,边检测出这种泄漏问题,将会非常有用,这里便会引用到了goroutine离线检测工具:goleak。

1.使用
func TestA(t *testing.T) {
defer goleak.VerifyNone(t)

// test logic here.
}
在进行单元测试时可以直接使用,非常方便。

例如:下面是有异常的goroutine,使用goleak检测的结果:

found unexpected goroutines:
[Goroutine 23 in state chan receive, with go.uber.org/goleak.TestIgnoreCurrent.func2.1 on top of the stack:
goroutine 23 [chan receive]:
go.uber.org/goleak.TestIgnoreCurrent.func2.1(0xc000118c60)
/go_proj/goleak/leaks_test.go:111 +0x34
created by go.uber.org/goleak.TestIgnoreCurrent.func2
/go_proj/goleak/leaks_test.go:110 +0x11d
]
2.原理
像这种检测工具具体怎么实现的呢?比较好奇,就阅读了一下源码,发现源码非常的少,里面有很多技巧与学习的东西。

第一个点:如何检测?

这里的检测是尝试20次,每次最大时间睡眠100ms(允许耗时的goroutine运行)。每次检测过程为:过滤掉传入的goroutine,通过runtime.Stack获取到各种状态的goroutine,20次之后如果还有剩余的goroutine,那么就是有问题的,输出出来就好了。

内部实现的一些技巧:

过滤函数

对外暴露IgnoreTopFunction接口允许传入goroutine关键字符串,内部会去做匹配,用户不用关心细节,内部函数作为参数,调用addFilter,还支持传入当前goroutine,调用IgnoreCurrent。

func IgnoreTopFunction(f string) Option {
return addFilter(func(s stack.Stack) bool {
return s.FirstFunction() == f
})
}
func IgnoreCurrent() Option {
excludeIDSet := map[int]bool{}
for _, s := range stack.All() {
excludeIDSet[s.ID()] = true
}
return addFilter(func(s stack.Stack) bool {
return excludeIDSet[s.ID()]
})
}
func addFilter(f func(stack.Stack) bool) Option {
return optionFunc(func(opts *opts) {
opts.filters = append(opts.filters, f)
})
}
获取所有goroutine的栈信息

内部通过定义stack结构体,创建私有的getStacks进行解析,getStacks会解析出多个stack结构,内部实现原理为读取runtime.Stack的所有goroutine信息。

// Stack represents a single Goroutine's stack.
type Stack struct {
id int
state string
firstFunction string
fullStack *bytes.Buffer
}
最后,会获取到每个goroutine的id、状态、函数名,栈信息。
————————————————
版权声明:本文为CSDN博主「guangcheng0312q」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/guangcheng0312q/article/details/125326007

标签:goroutine,Stack,---,goleak,func,go,stack
From: https://www.cnblogs.com/ExMan/p/16612988.html

相关文章

  • Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.
    maven构建报错:Causedby:org.apache.maven.plugin.MojoExecutionException:ErrorassemblingWAR:webxmlattributeisrequired(orpre-existingWEB-INF/web.xmli......
  • 02 - 站在内核角度分析NIO实现原理
    输入IO与输出IO原理内核态:CPU可以访问内存所有数据,包括外围设备,例如硬盘,网卡;用户态:(独立创建应用程序)只能受限的访问内存,且不允许访问外围设备.占用CPU的......
  • python学习目录04-模块的循环导入
    循环导入#循环导入:大型的python项目中,需要很多python文件,由于架构不当,可能会出现模块之间的相互导入A:模块deftest():f()B:模块deff():......
  • AcWing算法基础课---第一讲基础算法---02二分
    整数二分模板l=mid这个模板mid需要+1intbsearch_1(intl,intr){while(l<r){intmid=l+r>>1;if(check(mid))r=mid;//check()判断mid是否满足性......
  • 参数校验---gin框架内置使用validator
    type SignUpParam struct {    Age       uint8 `json:"age" binding:"gte=1,lte=130"`    Name      string`json:"name" binding:"req......
  • python学习目录03-包的__init文件
    包的__init__操作#__init__.py文件:当导入包的时候,默认调用__init__.py文件#作用:#1.当导入包的时候,把一些初始化的函数,变量,类定义在__init__.py文件中......
  • Stream流-流式思想概述和获取流
    流式思想概述整体来看,流式思想类似于工厂车间的“生产流水线”。  当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个“模型”......
  • Kibana - 总结
    参考资料1、官方网站:https://www.elastic.co/guide/en/kibana/current/index.htmlKibana介绍Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使......
  • 2 Django-message组件
    假设:你正在做一个订单支付平台,其中用到了删除/撤销订单问题。想给予用户一些提示。可以用到Django的message组件。该组件通过第一次请求,写入提示信息并返回重定向,第二次请......
  • 具名插槽-动态传入数据
    父组件:<template><!--nav-bar只给一个插槽动态传入数据--><nav-bar><templatev-slot:[position]><ahref="#">注册</a></template></n......