PouchContainer Goroutine Leak 检测实践

PouchContainer是阿里巴巴开源的容器运行时产品,也是golang项目,大量运用goroutine实现容器、镜像和日志管理。但goroutine可能出现leak,会吞噬资源致系统变慢或崩溃。本文将介绍PouchContainer在goroutine leak方面的检测实践。

0. 引言

PouchContainer 是阿里巴巴集团开源的一款容器运行时产品,它具备强隔离和可移植性等特点,可用来帮助企业快速实现存量业务容器化,以及提高企业内部物理资源的利用率。

PouchContainer 同时还是一款 golang 项目。在此项目中,大量运用了 goroutine 来实现容器管理、镜像管理和日志管理等模块。goroutine 是 golang 在语言层面就支持的用户态 “线程”,这种原生支持并发的特性能够帮助开发者快速构建高并发的服务。

虽然 goroutine 容易完成并发或者并行的操作,但如果出现 channel 接收端长时间阻塞却无法唤醒的状态,那么将会出现 goroutine leak 。 goroutine leak 同内存泄漏一样可怕,这样的 goroutine 会不断地吞噬资源,导致系统运行变慢,甚至是崩溃。为了让系统能健康运转,需要开发者保证 goroutine 不会出现泄漏的情况。 接下来本文将从什么是 goroutine leak, 如何检测以及常用的分析工具来介绍 PouchContainer 在 goroutine leak 方面的检测实践。

1. Goroutine Leak

在 golang 的世界里,你能支配的土拨鼠有很多,它们既可以同时处理一大波同样的问题,也可以协作处理同一件事,只要你指挥得当,问题就能很快地处理完毕。没错,土拨鼠就是我们常说的 goroutine ,你只要轻松地 go 一下,你就拥有了一只土拨鼠,它便会执行你所指定的任务:

func main() {
    waitCh := make(chan struct{})
    go func() {
        fmt.Println("Hi, Pouch. I'm new gopher!")
        waitCh <- struct{}{}
    }()

    <-waitCh
}

正常情况下,一只土拨鼠完成任务之后,它将会回笼,然后等待你的下一次召唤。但是也有可能出现这只土拨鼠很长时间没有回笼的情况。

func main() {
        // /exec?cmd=xx&args=yy runs the shell command in the host
        http.HandleFunc("/exec", func(w http.ResponseWriter, r *http.Request) {
                defer func() { log.Printf("finish %v\n", r.URL) }()
                out, err := genCmd(r).CombinedOutput()
                if err != nil {
                        w.WriteHeader(500)
                        w.Write([]byte(err.Error()))
                        return
                }
                w.Write(out)
        })
        log.Fatal(http.ListenAndServe(":8080", nil))
}

func genCmd(r *http.Request) (cmd *exec.Cmd) {
        var args []string
        if got := r.FormValue("args"); got != "" {
                args = strings.Split(got, " ")
        }

        if c := r.FormValue("cmd"); len(args) == 0 {
                cmd = exec.Command(c)
        } else {
                cmd = exec.Command(c, args...)
        }
        return
}

上面这段代码会启动 HTTP Server,它将允许客户端通过 HTTP 请求的方式来远程执行 shell 命令,比如可以使用 curl "{ip}:8080/exec?cmd=ps&args=-ef" 来查看 Server 端的进程情况。执行完毕之后,土拨鼠会打印日志,并说明该指令已执行完毕。

原文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值