我有一个漫长的运行GO程序(1.18版),该程序每秒同时使用Resty同时发送数百个获取请求到远程。每个获取请求都是单独的go-Routine,它使用相同的resty客户端。
远程服务器 https://api.abcd.com is nginx/1.19.2(http/2),ip地址为11.11.11.11和22.22.22.22。是的,此远程服务器具有多个IP地址。
设置Resty客户端时,我使用主机名
setBaseurl(“ https://api.abcd.com”)
传输配置默认是Resty中的一种。
traceinfo()在Resty客户端启用。跟踪信息中有一个“ ISConnreed”字段。这实际上来自GO HTTPTRACE软件包中的struct 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确定基于hostName(api.abcd.com)或IP地址的“连接重复使用”?
问题2:GO HTTP软件包空闲连接池实际上是映射,键是struct类型ConnectMethodkey。此结构中的ADDR字段是主机名或IP地址?
type connectMethodKey struct {
proxy, scheme, addr string
onlyH1 bool
}
这就是我在traceinfo()中发现的。当程序在开始时运行时,所有请求均发送到11.11.11.11:443。几分钟后,所有请求都发送到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不再使用空闲连接?我认为那些闲置连接已经超时了。
I have a long running GO program(version 1.18) which sends hundreds of GET requests simultaneously per second using RESTY to the remote https://api.abcd.com. Each GET request is a separate go-routine which uses the same RESTY client.
remote server https://api.abcd.com is nginx/1.19.2(HTTP/2), IP address is 11.11.11.11 and 22.22.22.22. Yes, this remoter server has multiple IP addresses.
I use hostname when setting RESTY client
SetBaseURL("https://api.abcd.com")
Transport configuration are default one in RESTY.
TraceInfo() is enabled on RESTY client side. There is a "IsConnReused" field in the trace info. This IsConnReused actually comes from struct GotConnInfo in GO httptrace package:
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
}
question 1: GO httptrace determine "Connection reused" based on hostname(api.abcd.com) or IP address?
question 2: GO http package idle connection pool is actually a map, key is a struct type connectMethodKey. The addr field in this struct is hostname or IP address?
type connectMethodKey struct {
proxy, scheme, addr string
onlyH1 bool
}
This is what I found in TraceInfo(). When the program runs at the beginning, all requests are sent to 11.11.11.11:443. Few minutes later, all requests are sent to 22.22.22.22, no 11.11.11.11 anymore. Then, few minutes later, all requests start to sent to 11.11.11.11 again, no 22.22.22.22 this time.
question 3: when requests start to sent to 22.22.22.22, the socket connections to 11.11.11.11 are idle, why GO http does not use idle connections anymore? I don't think those idle connection has already timeout.
发布评论
评论(1)
HTTPTRACE.GOTCONNINFO.REUSUSE
跟踪是否将TCP连接用于另一个HTTP请求。它是每个IP地址。addr
是主机名
可能是IP,但是如果将请求发送到
http://127.0.0.0.1/
之类的内容。如果您使用http 1,它的工作方式可能会有所不同。
有了它,每个请求都需要自己的TCP连接。随后的请求可以重复使用TCP连接,但是如果要并行运行请求,则需要建立多个TCP连接。每个连接都会使用不同的IP地址,您会看到流量均匀分布。
使用HTTP/2,可以将单个TCP连接用于多个并行请求。该连接使用一个IP地址。
这就是如何计算新请求是否可以使用打开连接的方式:
https://cs.opensource.google/go/x/net/+/69896b71:http2/transport.go;l=881;drc=69896b714898bee1e3403560cd2e1870bcc8bd35;bpv=1;bpt=1
Play使用这些婴儿车,可以通过多个TCP连接分配流量。
httptrace.GotConnInfo.Reused
tracks if TCP connection was used for another HTTP request. It is per IP address.addr
ishostname
Could be an IP though if you send request to something like
http://127.0.0.1/
.It could work differently if you use HTTP 1.
With it, every request requires the own TCP connection. Subsequent requests may reuse TCP connection, but if you want to run requests in parallel, you need to establish multiple TCP connections. Every connection would use a different IP address, and you would see traffic evenly distributed.
With HTTP/2 a single TCP connection can be used for multiple parallel requests. That connection uses a single IP address.
This is how GO calculates if a new request can use open connection:
https://cs.opensource.google/go/x/net/+/69896b71:http2/transport.go;l=881;drc=69896b714898bee1e3403560cd2e1870bcc8bd35;bpv=1;bpt=1
Play with these prams to distribute the traffic across multiple TCP connections.