前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >goroutine泄漏检测神器---goleak

goroutine泄漏检测神器---goleak

作者头像
公众号guangcity
发布2022-06-20 19:06:55
8920
发布2022-06-20 19:06:55
举报
文章被收录于专栏:光城(guangcity)

goroutine泄漏检测神器---goleak

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

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

1.使用

代码语言:javascript
复制
func TestA(t *testing.T) {
 defer goleak.VerifyNone(t)

 // test logic here.
}

在进行单元测试时可以直接使用,非常方便。

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

代码语言:javascript
复制
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。

代码语言:javascript
复制
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信息。

代码语言:javascript
复制
// Stack represents a single Goroutine's stack.
type Stack struct {
 id            int
 state         string
 firstFunction string
 fullStack     *bytes.Buffer
}

最后,会获取到每个goroutine的id、状态、函数名,栈信息。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • goroutine泄漏检测神器---goleak
    • 1.使用
      • 2.原理
      相关产品与服务
      检测工具
      域名服务检测工具(Detection Tools)提供了全面的智能化域名诊断,包括Whois、DNS生效等特性检测,同时提供SSL证书相关特性检测,保障您的域名和网站健康。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档