httpclient 默认启用keepalive,使用链接池复用tcp链接,设置client.Transpost.DisableKeepAlives =false 禁用长链接。

在keepalive开启的情况下:
如果一个请求成功后,返回了resp,但是没有读取完body的内容,而且没有close body,会造成readLoop这个goroutine无法正常结束而泄漏,而且也不会被链接池复用。

如果一个请求成功后,返回了resp,但是没有读取完body的内容,close了body,readLoop携程会正常结束,但是无法回收到链接池复用,成为‘一次性’短链接。

如果一个请求成功后,返回了resp,读取完了body的内容,不管有没有close body,这个链接都会放回链接池复用。

一般情况下httpclient用全局变量保存一个实例即可。如果每次请求都创建新的httpclient,而且每次都使用新定义的transport,会为每一个请求都创建一个链接池保存存活链接,造成内存泄露,因为链接池时保存在transport结构中的,应该全局复用。

下面是httpclient从请求发起到resp被读取,关闭的整个生命周期。纵向是向下函数调用,横向是函数内的顺序执行,省略了二次请求时链接复用从链接池取链接的过程。


viggo
134 声望2 粉丝

热爱coding