[英]Difference of DialContext KeepAlive and Transport IdleTimeout of go http.Client
[英]Go Transport connection keepalive when DNS changes
我目前正在使用go编写代理。 我正在使用标准库中的ReverseProxy和标准库中的默认Transport 。
假设对于这个问题,我们只有一个代理的原始主机。 我们将DisableKeepAlives
设置为false,允许到原始服务器的多个空闲连接,并将IdleConnTimeout
设置为60秒。
假设客户端每10秒使用代理向原始主机发出一个请求。 第一个连接将导致DNS查找以查找原始主机的IP。 传输将保持与该IP的连接打开,该连接将永远不会关闭,因为我们在超时之前一直在重复使用它。 缓存连接的方式在主机而不是IP上。
现在,假设该主机的DNS记录已更改并指向新IP。 我们仍将保持开放至原始IP的连接,并且由于该连接永远不会关闭,因此我们永远无需建立新连接,因此也不会开始与新IP通信(假设原始主机在连接后仍保持活动状态)。 dns更改)。
如果我们要设计一种能够响应DNS更改的系统,那么哪种模式合适? 我的一个想法是有一个无限循环,它每N秒关闭一次空闲连接 。 这对于上面的玩具示例来说是可行的,但是如果我们有更多的流量通过,那么很有可能在刷新期间正在处理请求。
替代方法是仅设置连接可以存活的最大时间长度。 但是,我看不到一种方法来操纵标准库来实现这一目标。
任何人都可以建议对DNS更改做出响应的设计吗?
从问题来看,似乎代理实现被设计为使用ip作为端点。
如果无法避免将主机名用作目标端点,则可以配置httputil.ReverseProxy.Director
解析主机名。 以牺牲查找时间为代价(可以将其配置为仅在dns ttl过期时进行查找),您将获得实时更新的目标端点,同时仍使用http.Transport
的连接缓存。
Director
:
func director(req *http.Request) {
addrs, err := net.LookupHost("yourdomain.com")
if err != nil {
handle(err)
}
if len(addrs) < 1 {
handle(fmt.Errorf("No addresses found"))
}
req.URL.Host = addrs[0]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.