Go http client 连接池不复用的问题
Posted 码农桃花源
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go http client 连接池不复用的问题相关的知识,希望对你有一定的参考价值。
当 http client 返回值为不为空,只读取 response header,但不读 body 内容就执行 response.Body.Close(),那么连接会被主动关闭,得不到复用。
测试代码如下:
// xiaorui.cc
func HttpGet() {
for {
fmt.Println("new")
resp, err := http.Get("http://www.baidu.com")
if err != nil {
fmt.Println(err)
continue
}
if resp.StatusCode == http.StatusOK {
continue
}
resp.Body.Close()
fmt.Println("go num", runtime.NumGoroutine())
}
}
正如大家所想,除了 HEAD Method 外,很少会有只读取 header 的需求吧。
话说,golang httpclient 需要注意的地方着实不少。
-
如没有 response.Body.Close(),有些小场景造成 persistConn 的 writeLoop 泄露。 -
如 header 和 body 都不管,那么会造成泄露的连接干满连接池,后面的请求只能是 短连接
。
上下文
由于某几个业务系统会疯狂调用各区域不同的 k8s 集群,为减少跨机房带来的时延、兼容新老 k8s 集群 api、减少k8s api-server 的负载,故而开发了 k8scache 服务。在部署运行后开始对该服务进行监控,发现 metrics 呈现的 QPS 跟连接数不成正比,qps 为 1500,连接数为 10 个。开始以为触发 idle timeout 被回收,但通过历史监控图分析到连接依然很少。
以上是关于Go http client 连接池不复用的问题的主要内容,如果未能解决你的问题,请参考以下文章
面试官:为什么数据库连接池不采用 IO 多路复用?我懵逼了。。
面试官:为什么数据库连接池不采用 IO 多路复用?我懵逼了。。
聊一个不常见的面试题:为什么数据库连接池不采用 IO 多路复用