Http 在Go中使用DialContext的性能问题
我使用Go的内置Http 在Go中使用DialContext的性能问题,http,go,Http,Go,我使用Go的内置http.Client和net做了一个快速基准测试。与不使用相比,使用DialContext时会导致一些明显的性能问题 我基本上是在模仿我们公司的一个用例,在这个用例中,http.Client设置与默认配置相比,在完全用于相同的事情时,性能要差得多。我注意到对DialContext部分的注释使它运行得更快 基准测试只是打开一个线程池(本例中为8个)来创建到简单URL的连接,使用与线程数(8)相同大小的缓冲通道 以下是带有DialContext(2.266333805s)的代码:
http.Client
和net
做了一个快速基准测试。与不使用相比,使用DialContext
时会导致一些明显的性能问题
我基本上是在模仿我们公司的一个用例,在这个用例中,
http.Client
设置与默认配置相比,在完全用于相同的事情时,性能要差得多。我注意到对DialContext
部分的注释使它运行得更快
基准测试只是打开一个线程池(本例中为8个)来创建到简单URL的连接,使用与线程数(8)相同大小的缓冲通道
以下是带有DialContext
(2.266333805s)的代码:
输出时间为731.154103ms
结果之间的差异在程序的多次运行中是一致的
有人知道为什么会这样吗
谢谢
编辑:因此我尝试了net/http/httptrace
,并确保已完全读取并关闭了响应主体:
go func() {
for range c {
req, _ := http.NewRequest(http.MethodGet, url, nil)
req = req.WithContext(httptrace.WithClientTrace(req.Context(), &httptrace.ClientTrace{
GotConn: t.gotConn,
}))
resp, _ := httpClient.Do(req)
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}
wg.Done()
}()
使用DialContext
vs不使用它时的发现是有趣的
不使用拨号上下文:
time taken to run 200 requests: 5.639808793s
new connections: 1
reused connections: 199
time taken to run 200 requests: 5.682882723s
new connections: 8
reused connections: 192
使用拨号上下文:
time taken to run 200 requests: 5.639808793s
new connections: 1
reused connections: 199
time taken to run 200 requests: 5.682882723s
new connections: 8
reused connections: 192
它更快。。。但是为什么一个打开了8个新连接,而另一个只打开了1个?获得如此大差异的唯一方法是,如果一个传输正在重用连接,而另一个没有。为了确保可以重用连接,必须始终读取响应正文。在某些情况下,连接可能会在不显式读取正文的情况下被重用,但这永远无法保证,这取决于许多事情,如远程服务器关闭连接、响应是否被
传输
完全缓冲,以及请求上是否存在上下文
该包可以让您深入了解许多请求内部,包括连接是否被重用。有关示例,请参见
设置DisableKeepAlive
将始终阻止重新使用连接,从而使这两个连接都同样缓慢。总是这样读取响应将使两种响应速度相似:
req, _ := http.NewRequest(http.MethodGet, url, nil)
resp, err := httpClient.Do(req)
if err != nil {
// handle error
continue
}
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
如果你想知道在断开连接之前可以读取多少数据,你可以简单地用一个1)执行你的基准测试;2) 您正在调整
DialContext
中的几个设置,在另一个示例中,您将默认保留这些设置。您也根本没有检查响应。很可能在第一次运行后,您的连接因滥用而被拒绝。仅使用DialContext:http.DefaultTransport时也会发生同样的情况。(*http.Transport)。DialContext
:(我基本上是在模仿我们公司的一个用例,http.Client
设置在完全相同的情况下比默认配置的性能要差得多。我注意到对DialContext
部分的注释使它运行得更快。@JimB我以不同的顺序尝试了好几次,还有net/http/httptrace
表明您在重用连接方面是正确的。我还做了一些进一步的阅读,以确保响应正文总是被阅读。不过,我在帖子上添加了一个编辑部分来显示我的结果。介意看看吗?有显然,在初始请求调用的序列化方面存在一些差异,但最终这并不重要。您必须更深入地了解内部结构以了解原因,但单传输和客户端在并发请求速度方面还是有一定的限制。