分享
  1. 首页
  2. 文章

golang http连接池失效的几种情况及具体原因分析

caucy · · 5404 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

首先,连接池失效,问题产生背景是高频agent,agent 会发起大量的http 请求,但是,本想net/http 是支持长连接的,但是,几种情况,都产生了大量的time_wait,这里予以总结。

第一种情况是误用transport ,为了设置代理,为每个请求,都new 了一个transport 。

client := &http.Client{
 CheckRedirect: redirectPolicyFunc,
 Timeout: time.Duration(10)*time.Second,//设置超时
}
client.Transport = &http.Transport{
 Proxy: http.ProxyURL(proxyUrl),
} //设置代理ip

失效的原因,是client 是线程安全的,golang连接池的维度是transport, 在transport 里面维护了两个map,暂存连接。

第二种情况是没设置 MaxIdleConnsPerHost, 和连接的timeout, 一旦高频的连接超过MaxIdleConnsPerHost 的数目,同时超过超时,连接就会释放。正确的设置是实例化transport 的时候,评估好 connsPerHost, 如下:

var DefaultTransport RoundTripper = &Transport{
 ... 
 MaxIdleConnsPerHost: 1000,
 IdleConnTimeout: 90 * time.Second,
 ... 
}

第三种情况是resp.body 忘了读取,直接导致新请求会直接新建连接。其实可以理解,没read body 的socket, 如果直接复用,会产生什么样后果?所有使用这个套接字的连接都会错乱。 示例如下,

package main
import (
 "fmt"
 "html"
 "log"
 "net"
 "net/http"
 "time"
)
func startWebserver() {
 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
 })
 go http.ListenAndServe(":8080", nil)
}
func startLoadTest() {
 count := 0
 for {
 resp, err := http.Get("http://localhost:8080/")
 if err != nil {
 panic(fmt.Sprintf("Got error: %v", err))
 }
 resp.Body.Close()
 log.Printf("Finished GET request #%v", count)
 count += 1
 }
}
func main() {
 // start a webserver in a goroutine
 startWebserver()
 startLoadTest()
}

这里可以使用ss -s 查看连接数,如果不关心返回body ,可以直接丢弃

 io.Copy(ioutil.Discard, resp.Body) //Discard 是一个 io.Writer,对它进行的任何 Write 调用都将无条件成功

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
5404 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏