DNS更改时转移传输连接保持活动

时间:2018-01-24 11:15:40

标签: go networking tcp dns

我目前正在使用go编写代理。我使用标准库中的ReverseProxy以及标准库中的默认Transport

假设这个问题我们只有一个代理的源主机。我们将DisableKeepAlives设置为false,允许多个空闲连接到源服务器并将IdleConnTimeout设置为60秒。

假设客户端使用代理每10秒向源主机发出一个请求。第一个连接将导致DNS查找以查找原始主机的IP。传输将保持对该IP的连接,该连接将永远不会关闭,因为我们会在超时之前继续重复使用它。缓存连接的方式是在主机而不是IP上。

现在假设该主机的DNS记录更改并指向新IP。我们仍然可以将我们的连接打开到原始IP,并且因为它永远不会关闭,我们永远不需要建立新连接,因此不会开始与新IP通信(假设原始主机在之后仍处于活动状态dns改变)。

如果我们想要以对DNS变化做出响应的方式设计系统,那么哪种模式是合适的?我的一个想法就是有一个无限循环closes any idle connections每N秒存在一次。这适用于上面的玩具示例,但是在我们有更多交通流量的情况下,那么在冲洗期间请求将在飞行中的机会很大。

另一种方法是设置连接可以存活的最大时间长度。但是,我无法通过操作标准库来实现此目的。

任何人都可以就可以响应DNS更改的设计提出建议吗?

1 个答案:

答案 0 :(得分:2)

从问题来看,似乎代理实现的目的是将ip用作端点。

如果您无法避免使用主机名作为目标端点,则可以配置httputil.ReverseProxy.Director来解析主机名。以查找时间为代价(可以配置为仅在dns ttl到期时查找),您将获得实时更新的目标端点,同时仍然使用http.Transports连接缓存。

示例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]
}