<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Golang Http Client on 备忘</title>
    <link>https://blog.witd.in/tags/golang-http-client/</link>
    <description>Recent content in Golang Http Client on 备忘</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>kongfei605@gmail.com (kongfei)</managingEditor>
    <webMaster>kongfei605@gmail.com (kongfei)</webMaster>
    <copyright>(c) 2022 witd. All rights reserved</copyright>
    <lastBuildDate>Mon, 25 Feb 2019 10:06:41 +0800</lastBuildDate>
    
	<atom:link href="https://blog.witd.in/tags/golang-http-client/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>golang http client 关闭重用连接两种方法</title>
      <link>https://blog.witd.in/2019/02/25/golang-http-client-%E5%85%B3%E9%97%AD%E9%87%8D%E7%94%A8%E8%BF%9E%E6%8E%A5%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95/</link>
      <pubDate>Mon, 25 Feb 2019 10:06:41 +0800</pubDate>
      <author>kongfei605@gmail.com (kongfei)</author>
      <guid>https://blog.witd.in/2019/02/25/golang-http-client-%E5%85%B3%E9%97%AD%E9%87%8D%E7%94%A8%E8%BF%9E%E6%8E%A5%E4%B8%A4%E7%A7%8D%E6%96%B9%E6%B3%95/</guid>
      <description>&lt;p&gt;同事有个模块会定期获取宿主机上的所有容器信息，代码中使用http client 请求docker engine获取容器信息。运行后收到用户反馈，程序导致系统fd泄漏,修复后代码如下，比原来代码多了一句 &lt;code&gt;req.Close=true&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    client := &amp;amp;http.Client{
        Timeout: time.Duration(timeout) * time.Millisecond,
        Transport: &amp;amp;http.Transport{
            Dial: unixDial,
        },
    }

    req, err := http.NewRequest(&amp;quot;GET&amp;quot;, url, nil)
    if err != nil {
        return nil, fmt.Errorf(&amp;quot;NewRequest(): url = %s, err = %s&amp;quot;, url, err)
    }

    req.Close = true // fd leak without setting this
    resp, err := client.Do(req)
    ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;因为我自己有个清理容器数据的代码也有类似逻辑。代码如下，但是这个清理容器的模块是运行一次就退出的（磁盘资源紧张时才运行） 所以没有这个问题。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  tr := &amp;amp;http.Transport{Dial: fakeDial, } 
    client := &amp;amp;http.Client{Transport: tr}
    resp, err := client.Get(&amp;quot;http://localhost/containers/json&amp;quot;)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;翻了下源码发现这段注释&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    // Close indicates whether to close the connection after
    // replying to this request (for servers) or after sending this
    // request and reading its response (for clients).
    //
    // For server requests, the HTTP server handles this automatically
    // and this field is not needed by Handlers.
    //
    // For client requests, setting this field prevents re-use of
    // TCP connections between requests to the same hosts, as if
    // Transport.DisableKeepAlives were set.
    Close bool
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
  </channel>
</rss>