我目前正在使用go编写代理。我使用标准库中的ReverseProxy以及标准库中的默认Transport。
假设这个问题我们只有一个代理的源主机。我们将DisableKeepAlives
设置为false,允许多个空闲连接到源服务器并将IdleConnTimeout
设置为60秒。
假设客户端使用代理每10秒向源主机发出一个请求。第一个连接将导致DNS查找以查找原始主机的IP。传输将保持对该IP的连接,该连接将永远不会关闭,因为我们会在超时之前继续重复使用它。缓存连接的方式是在主机而不是IP上。
现在假设该主机的DNS记录更改并指向新IP。我们仍然可以将我们的连接打开到原始IP,并且因为它永远不会关闭,我们永远不需要建立新连接,因此不会开始与新IP通信(假设原始主机在之后仍处于活动状态dns改变)。
如果我们想要以对DNS变化做出响应的方式设计系统,那么哪种模式是合适的?我的一个想法就是有一个无限循环closes any idle connections每N秒存在一次。这适用于上面的玩具示例,但是在我们有更多交通流量的情况下,那么在冲洗期间请求将在飞行中的机会很大。
另一种方法是设置连接可以存活的最大时间长度。但是,我无法通过操作标准库来实现此目的。
任何人都可以就可以响应DNS更改的设计提出建议吗?
答案 0 :(得分:2)
从问题来看,似乎代理实现的目的是将ip用作端点。
如果您无法避免使用主机名作为目标端点,则可以配置httputil.ReverseProxy.Director
来解析主机名。以查找时间为代价(可以配置为仅在dns ttl到期时查找),您将获得实时更新的目标端点,同时仍然使用http.Transport
s连接缓存。
示例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]
}