登录
首页 >  Golang >  Go问答

为什么在关闭响应正文后调用http.Get(..)会导致资源泄漏?

来源:stackoverflow

时间:2024-02-07 22:27:24 459浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《为什么在关闭响应正文后调用http.Get(..)会导致资源泄漏?》,聊聊,希望可以帮助到正在努力赚钱的你。

问题内容

func getrespbody(link string) (string, error) {

    res, err := http.get(link)
    if err != nil {
        return "", err
    }
    defer res.body.close()
    resbody, err := ioutil.readall(res.body)
    if err != nil {
        return "", err
    }
    return string(resbody), nil
}

我有一个测试 -

func TestRespBody(t *testing.T) {
    defer goleak.VerifyNone(t)
    getRespBody("https://google.com")
}

为什么会导致资源泄漏?

我希望 defer res.body.close() 能够负责关闭 resp body 并且不会出现资源泄漏。这里应该做什么来防止资源泄漏?


正确答案


当您关闭响应正文时,http 调用中使用的底层 tcp 连接默认不会关闭,因为重用它们是有利的。这是正常现象,但这也是导致误报泄漏的原因。

如果将disablekeepalives 设置为true,则可以修改默认的http 客户端行为。

如果您重构函数以接收 http 客户端作为参数,则可以制作一个显式关闭连接的 http 客户端,而不是将其保存在连接池中,只是在该测试的范围内。

func getResBody(c http.Client, url string) (string, error) {
    res, err := c.Get(url)
    if err != nil {
        return "", err
    }
    defer res.Body.Close()
    resBody, err := ioutil.ReadAll(res.Body)
    if err != nil {
        return "", err
    }
    return string(resBody), nil
}


func Test_getResBody(t *testing.T) {
    defer goleak.VerifyNone(t)

    client := http.Client{
        Transport: &http.Transport{
            DisableKeepAlives: true,
        },
    }

    getResBody(client, "https://google.com")
}

今天关于《为什么在关闭响应正文后调用http.Get(..)会导致资源泄漏?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>