查看HTTP空闲连接池和HTTP跟踪



我有一个长时间运行的GO程序(版本1.18),它使用rest向远程https://api.abcd.com每秒同时发送数百个GET请求。每个GET请求都是一个单独的go例程,使用相同的rest客户端。

远程服务器https://api.abcd.com是nginx/1.19.2(HTTP/2), IP地址是11.11.11.11和22.22.22.22。是,这个远程服务器有多个IP地址。

我在设置rest客户端时使用主机名SetBaseURL("https://api.abcd.com")

传输配置是rest中的默认配置。

TraceInfo()在rest客户端是启用的。有一个"IsConnReused"字段。这个isconnreuse实际上来自GO httptrace包中的GotConnInfo结构体:

type GotConnInfo struct {
Conn net.Conn
// Reused is whether this connection has been previously used for another HTTP request.
Reused bool
// WasIdle is whether this connection was obtained from anidle pool.
WasIdle bool
// IdleTime reports how long the connection was previously idle, if WasIdle is true.
IdleTime time.Duration
}

问题1:GO httptrace确定"连接被重用"基于主机名(api.abcd.com)或IP地址?

问题2:GO的http包空闲连接池实际上是一个map, key是一个struct类型connectMethodKey。这个结构体中的addr字段是主机名还是IP地址?

type connectMethodKey struct {
proxy, scheme, addr string
onlyH1              bool
}

这是我在TraceInfo()中发现的。当程序开始运行时,所有请求都被发送到11.11.11.11:43。几分钟后,所有的请求都发送到22.22.22.22,不再是11.11.11.11。然后,几分钟后,所有的请求又开始发送到11.11.11.11,而不是22.22.22.22。

问题3:当请求开始发送到22.22.22.22时,到11.11.11.11的套接字连接是空闲的,为什么GO http不再使用空闲连接?我认为那些空闲的连接还没有超时。

问题1:GO httptrace确定"连接被重用";基于主机名(api.abcd.com)或IP地址?

httptrace.GotConnInfo.Reused跟踪TCP连接是否用于另一个HTTP请求。

问题2:GO http包空闲连接池实际上是一个映射,key是一个结构类型connectMethodKey。该结构体中的addr字段主机名还是IP地址?

addrhostname

可以是一个IP,但如果你发送请求到http://127.0.0.1/之类的东西。

问题3:当请求开始发送到22.22.22.22时,套接字到11.11.11.11的连接是空闲的,为什么GO http不使用idle连接了吗?我不认为那些闲置的连接已经超时。

如果您使用HTTP 1,可能会有不同的工作方式。有了它,每个请求都需要自己的TCP连接。后续请求可能重用TCP连接,但如果希望并行运行请求,则需要建立多个TCP连接。每个连接将使用不同的IP地址,并且您将看到流量均匀分布。

使用HTTP/2,单个TCP连接可以用于多个并行请求。该连接使用单个IP地址。

这是GO如何计算一个新的请求是否可以使用打开的连接:

https://cs.opensource.google/go/x/net/+/69896 b71: http2/transport.go; l = 881;刚果民主共和国= 69896 b714898bee1e3403560cd2e1870bcc8bd35; bpv = 1;双极性晶体管= 1

使用这些程序在多个TCP连接中分配流量。

最新更新