2025年3月14日 星期五 甲辰(龙)年 月十三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Go语言

golang http client 关闭重用连接两种方法

时间:02-16来源:作者:点击数:13

同事有个模块会定期获取宿主机上的所有容器信息,代码中使用http client 请求docker engine获取容器信息。运行后收到用户反馈,程序导致系统fd泄漏,修复后代码如下,比原来代码多了一句 req.Close=true

  • client := &http.Client{
  • Timeout: time.Duration(timeout) * time.Millisecond,
  • Transport: &http.Transport{
  • Dial: unixDial,
  • },
  • }
  • req, err := http.NewRequest("GET", url, nil)
  • if err != nil {
  • return nil, fmt.Errorf("NewRequest(): url = %s, err = %s", url, err)
  • }
  • req.Close = true // fd leak without setting this
  • resp, err := client.Do(req)
  • ...

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

  • tr := &http.Transport{Dial: fakeDial, }
  • client := &http.Client{Transport: tr}
  • resp, err := client.Get("http://localhost/containers/json")
  • if err != nil {
  • return nil, err
  • }
  • defer resp.Body.Close()

翻了下源码发现这段注释

  • // 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

http 1.1默认是保持keep-alive 的,所以如果每次请求都new 一个xin的client,就会造成fd泄漏。 按照注释,在new client时,把keep-alive 设置为disable 就可以解决这个问题。修改后代码如下

  • tr := &http.Transport{Dial: fakeDial, DisableKeepAlives: true}
  • client := &http.Client{Transport: tr}
  • resp, err := client.Get("http://localhost/containers/json")
  • if err != nil {
  • return nil, err
  • }
  • defer resp.Body.Close()

问题1 req.Close 和transport DisableKeepAlives 如何实现 http keep-alive:close 的? 如何达到相同目的的? 问题2 使用时怎么样更科学 更安全? 长连接? 短连接?

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐